首页
社区
课程
招聘
[求助]请教三道很简单的算法题。。。我没有KX了,只好发在这里了o(︶︿︶)o
发表于: 2012-6-16 01:22 2693

[求助]请教三道很简单的算法题。。。我没有KX了,只好发在这里了o(︶︿︶)o

2012-6-16 01:22
2693
这些题是南京邮电大学第四届大学生程序设计竞赛之预赛的题。说白了就是大一新生选拔的题。很简单。求C的源码,如果用C++做的话,很简单,用sort就行了。但是如果用C的话,我总是超时,实在不知道该怎么办了,麻烦大家都做一下好吗?然后http://acm.njupt.edu.cn/acmhome/contest.do?&method=contestDetail&contestId=158
在这里提交一下源码,看看答案通过了没有,如果答案通过了,麻烦你把源码贴上来好吗?谢谢了。


第一题:

A.  Sorting Problem I
题目描述:
openxxx喜欢一切有序的事物,现在有一串数字,openxxx希望以最小的代价对这串数字从小到大进行排序(实现非递减序)。
openxxx只会交换任意两个相邻的数字,每做一次交换,就要消耗openxxx一格的体力值,当然openxxx希望消耗的体力值越少越好,你能计算出openxxx至少要消耗多少格体力值吗?
输入格式:
多组测试数据,每组数据第一行包含一个正整数N(1<=N<=500)表示这串数字的个数,第二行包含N个正整数x1 x2 x3 …… xN(1<=xi<=N,1<=i<=N)用来描述这串原始数字序列,任意两个相邻数字之间用一个空格隔开。 
输出格式:
每组测试数据对应一行输出,仅包含一个整数p,表示最少需要消耗的体力值数。
样例输入:
2
1 2
3
3 1 2
2
1 1
样例输出:
0
2
0

第二题:
B.  Sorting Problem II
题目描述:
openxxx喜欢一切有序的事物,现在有一串数字,openxxx希望对这串数字从小到大进行排序(实现非递减序)。
openxxx可以交换任意两个数字,每做一次交换,就要消耗openxxx一格体力值,openxxx希望恰好在消耗了K格体力值的情况下完成排序,请你判断是否可能存在这样的情况。
输入格式:
多组测试数据,每组数据第一行包含一个正整数N(1<=N<=500)表示这串数字的个数,第二行包含N个正整数恰好是1~N的某一排列,相邻数字之间用一个空格隔开。第三行包含一个正整数M(1<=M<=500),接下来M行,每行包含一个非负整数K(0<=K<=50000),其含义见题目描述。 
输出格式:
每组测试数据对应M行输出,每行输出一个字符串 “YES”或者“NO”(不包括双引号),存在恰好消耗了K格体力值的情况下完成排序则输出“YES”,否则输出“NO”。
样例输入:
2
2 1
2
0
1
样例输出:
NO
YES

第三题
C.  Arithmetic Progression
题目描述:
如果一个数列从第二项起,每一项与它的前一项的差等于同一个常数,这个数列就叫做等差数列,这个常数叫做等差数列的公差。 十分喜欢等差数列,他给你一个数列 , ,他想知道有多少个子序列是等差数列,且公差的绝对值不超过 。所谓子序列为:在这个数列里,任取若干多项,不改变它们在原来数列中的先后次序,得到的数列称为是原来数列的一个子数列。(注意:等差数列至少2项)。
输入格式:
输入第一行为一个正整数 , 组测试数据,每组测试数据第一行为两个正整数 和 ,第二行为 个整数 。 
输出格式:
对于每组测试数据输出一行,仅包含一个整数,为满足条件的子序列的个数,答案对1000000007取模。
样例输入:
1
3 3
1 2 3
样例输出:
4

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (14)
雪    币: 5421
活跃值: (3571)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
哦哦,不好意思,那个网址发错了
应该是:

http://acm.njupt.edu.cn/acmhome/contest.do?&method=contestDetail&contestId=158
2012-6-16 01:40
0
雪    币: 622
活跃值: (294)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
3
第一题,用指针做冒泡排序,同时判断要交换的是否为当前元素,若是,则可节约一步。

第二题,用最费时的排序法求得最大值,若存在第一题的最小值<k<最大值,则成立。

第三题,首先求得数列中最大值与最小值的差,然后对数列中每个元素向后验证有无从差的负绝对值到正绝对值的存在。若存在则子数列数目+1。

趴床上爪机上网,就不去开机堆代码了。

不过,有这么多叙述,在这个临近暑假的时刻,你不会告诉我们说,其实你这学年DOTA打得不错吧?
2012-6-16 01:49
0
雪    币: 5421
活跃值: (3571)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
哪有刀塔。。。你自己去看那个网址啦,这是早都过去了的比赛啦,我只是自己想做一做罢了,但就是做不出来。。。

恩人,明早你能贴一份C的代码吗
2012-6-16 01:52
0
雪    币: 157
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
ACMer路过。
第一题和第二题a了,第三题因为楼主的题目没有给全,猜了一个题意做,TLE。
# include <stdio.h>

int main ()
{
    int n, i, j, cnt, a[510] ;
    while (~scanf ("%d",&n))
    {
        for(i = 0 ; i < n ; i++)
            scanf ("%d", &a[i]) ;
        cnt = 0 ;
        for (i = n-1 ; i > 0 ; i--)
            for (j = 0 ; j < i; j++) if (a[j]>a[j+1])
            {
                cnt++ ;
                a[j]^= a[j+1]^=a[j]^=a[j+1];
            }
        printf ("%d\n", cnt) ;
    }
    return 0 ;
}

# include <stdio.h>
# include <string.h>

int vis[510], a[510] ;
int main ()
{
    int n, m, k ;
    int i, j, cnt, tmp, p, q  ;
    while (~scanf ("%d",&n))
    {
        for(i = 1 ; i <= n ; i++)
            scanf ("%d", &a[i]) ;
        cnt = 0 ;
        for (i = 1 ; i <= n ; i++)
        {
            while (a[i] != i)
            {
                cnt++ ;
                p = a[i], q = i ;
                a

^=a[q]^=a

^=a[q] ;
            }
        }
        scanf ("%d", &m) ;
        while (m--)
        {
            scanf ("%d", &k) ;
            if (k < cnt || (k-cnt) % 2 == 1) puts ("NO") ;
            else puts ("YES") ;
        }
        
    }
    return 0 ;
}

2012-6-16 05:43
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
第一题还是用搜索排序比较好,因为这方法基本一个数字检测一次就排对了,以后基本不用对该数字再进行排序,也就是N个数字,只要排N-1次就可以了。(哎,看错题目 了,是相邻 两数字)
2012-6-16 08:23
0
雪    币: 622
活跃值: (294)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
7
额,这是我的解法,似乎看起来很长……

我只给关键过程。输入输出自己去搞吧。

#include <stdlib.h>

unsigned int SortCount(unsigned int numElements,unsigned int *pArray)
{
        unsigned int nCount,i,j;
        nCount=0;
        for (i=0;i<=numElements;i++)
        {
                for (j=i;j<=numElements;j++)
                {
                        if(*(pArray+i)>*(pArray+j))
                        {
                                nCount++;
                                *(pArray+i)^=*(pArray+j)^=*(pArray+i)^=*(pArray+j);
                        }
                }
        }
        return nCount;
}

int SortCountK(unsigned int numElements,unsigned int *pArray,unsigned int k)
{
        unsigned int i,minCount,maxCount,*pArrayb,*pMinElement,*pElement;
        int return_value=0;
        pArrayb=(unsigned int *)(malloc(numElements*sizeof(unsigned int)));
        for (i=0;i<numElements;i++)  *(pArrayb+i)=*(pArray+i);
        maxCount=SortCount(numElements,pArray);
        minCount=0;
        i=0;
        do
        {
                pElement=pArray+i;
                pMinElement=pElement;
                while(pElement<(pArrayb+numElements))
                {
                        if (*pMinElement>*pElement)  pMinElement=pElement;
                        pElement++;
                }
                if (pMinElement!=pArray+i)
                {
                        minCount++;
                        *pMinElement^=*pElement^=*pMinElement^=*pElement;
                }
        }while(i<=numElements);
        if (k>=minCount && k<=maxCount) return_value=1;
        return return_value;
}

unsigned int ArithmeticProgression(int numElements,int *pArray)
{
//结果在debug模式编译的程序是正确的,Release模式出错,不管了。
        int min,max,i,j,subArrayCount,*pElement,Dvalue;
        min=*pArray;
        max=min;
        i=1;
        do
        {
                if(min>*(pArray+i)) min=*(pArray+i);
                if(max<*(pArray+i)) max=*(pArray+i);
                i++;
        }while(i<numElements);
        i=max-min;
        max=i;
        min=0-i;
        subArrayCount=0;
        for (i=0;i<numElements;i++)
        {
                pElement=pArray+i;
                Dvalue=0;
                for (j=1;pElement<(pArray+numElements);j++)
                {
                        if((*pElement-*(pElement+j))>=min && (*pElement-*(pElement+j))<=max)
                        {
                                if (!Dvalue)
                                {
                                        Dvalue=*pElement-*(pElement+j);
                                }
                                else
                                {
                                        if ((*pElement-*(pElement+j))==Dvalue)
                                        {
                                                subArrayCount++;
                                                pElement+=j;
                                                j=0;
                                        }
                                }
                        }
                }
        }
        return   subArrayCount;
}
2012-6-16 10:46
0
雪    币: 157
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
LS你代码都没过编译器唉(第三题)。。。
2012-6-16 11:09
0
雪    币: 5421
活跃值: (3571)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
额,谢谢你能解答我的问题,不过。。。我要的是C的。。。
2012-6-16 13:02
0
雪    币: 5421
活跃值: (3571)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
[QUOTE=冬祭;1080434]ACMer路过。
第一题和第二题a了,第三题因为楼主的题目没有给全,猜了一个题意做,TLE。
# include <stdio.h>

int main ()
{
    int n, i, j, cnt, a[510] ;
    while (~scanf ("%d",&a...[/QUOTE]

木有哇,第三题我给全了。。。
2012-6-16 13:16
0
雪    币: 622
活跃值: (294)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
11
过编译器啊,我记事本写得……没去验证一下是不是能过编译的……

刚才修改了一下,已通过编译了。

不过我这边只有VS2011,所以代码最少符合VS2011认可的C语言规范。
2012-6-16 13:20
0
雪    币: 157
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
楼主,那些字母神马的都没显示出来。。。还有数据范围没给。目测是一个dp。。。
2012-6-16 14:23
0
雪    币: 5421
活跃值: (3571)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
题目真的我给全了。。。可能是这些题目太简单了吧,出题者就没有考虑数据范围的。。。
2012-6-16 17:03
0
雪    币: 157
活跃值: (10)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
14
你自己读一遍题目看哈通顺不通顺嘛。。。
2012-6-17 02:25
0
雪    币: 159
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
我看到算法就头疼!
2012-6-27 16:38
0
游客
登录 | 注册 方可回帖
返回
//