2013暑假ACM集训_12级周赛1

第一次周赛,5个基础题,1个可以找规律过的,一个哈希和查找的,英文题,仔细读题,不难

一开始只看每题的输入输出找水题,直接略过第一题,迅速A了后面4个水题,然后回来看剩下的A,B,E 

A题意理解,一开始想的是一位一位的加上去,看看是否满足各位和是10的倍数,然后觉得效率太低,而且模拟麻烦,容易出错,就放过了,最后找规律,模拟下也不难

B题和枚举的棋子很像,找下规律不难

E题是哈希表和二分查找的 POJ 2503  之前学了一点时间,哈希表还不会,问题是用C语言不会结束题目要求的输入,要不写个超时的代码也可以了,动都没动,这题直接放弃

A:

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2633&cid=1188

给定一个数,求出比他大的,并且是做小的满足:各个位上的数字之和是10的倍数  的一个数

因为给定的数的位数范围The length of x will not exceed 105.  所以要用字符串 模拟就行

 1 #include<stdio.h>

 2 #include<stdlib.h>

 3 #include<string.h>

 4 

 5 

 6 int main()

 7 {

 8     char str[100005];

 9     int a[100005];

10     int i,j,len,sum,n,h,l,last;

11     scanf("%d",&n);

12     for(h=0;h<n;h++)

13     {

14         scanf("%s",str);

15         len=strlen(str);

16         sum=0;

17         for(i=0;i<len;i++)

18         {

19             a[i]=str[i]-'0';

20             sum+=a[i];

21         } 

22         int num=0;

23         last=10-sum%10;

24         a[len-1]+=last;

25         if(a[len-1]<=9)

26         {

27             for(i=0;i<len;i++)

28             printf("%d",a[i]);

29             printf("\n");

30         }

31         else if(a[len-1]>9)

32         {

33            

34             for(i=len-2;i>=0;i--)

35             {

36                 num++;

37                 a[i]++;

38                 a[i]=a[i]%10;

39                 if(a[i])

40                 break;

41             }

42             if(i<0)

43             {

44                 printf("1");

45                 for(i=0;i<len-1;i++)

46                 printf("0");

47                 printf("9\n");

48             }

49             else

50             {

51                 a[len-1]=(a[len-1]+100000-num)%10;

52                 for(i=0;i<len;i++)

53                 printf("%d",a[i]);

54                 printf("\n");

55             }

56         }

57     }

58 }

59  
View Code

 

 

B:

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2667&cid=1188

简单的博弈,找规律发现只有最右下角的SG值为1,其余的都为0;

所以所有1的SG值异或的结果取决于最右下角的。

只有右下角为1,输出Alice,否则输出Bob

 1 #include<stdio.h>

 2 int a;

 3 int main()

 4 {

 5     int n,i,j,h,k,m;

 6 

 7     scanf("%d",&k);

 8     for(h=1;h<=k;h++)

 9     {

10         scanf("%d %d",&m,&n);

11         for(i=0;i<m;i++)

12         {

13             for(j=0;j<n;j++)

14             {

15                 scanf("%d",&a);

16             }

17         }

18         if(a)

19         printf("Alice\n");

20         else

21         printf("Bob\n");

22     }

23 }
View Code

 

C:

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2560&cid=1188

判断回文,注意空格不计入判断即可

思路可以是开一个新数组,for循环输入的数组,若不为空格字符,存到新数组里,最后对新数组判断是否回文

 1 #include<stdio.h>

 2 #include<stdlib.h>

 3 #include<string.h>

 4 

 5 int main()

 6 {

 7     char str[100010],s[100010];

 8     int i,j,len,flag=0;

 9     while(1)

10     {

11         flag=0;

12         gets(str);

13         if(strcmp(str,"2013")==0)

14         break;

15         j=0;

16         len=strlen(str);

17         for(i=0;i<len;i++)

18         {

19             if(str[i]!=' ')

20             {s[j]=str[i];

21             j++;}

22         }

23         for(i=0;i<j/2+1;j++)

24         {

25             if(s[i]!=s[j-i-1])

26             flag=1;

27             break;

28         }

29         if(flag==1)

30         printf("NO\n");

31         else

32         printf("YES\n");

33     }

34     return 0;

35 }

36  
View Code

 

D:

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2565&cid=1188

水题

 1 #include<stdio.h>

 2 int main()

 3 {

 4     int n,sum=0,i,a[10005];

 5     int m;

 6     scanf("%d",&n);

 7     for(i=1;i<=n;i++)

 8     scanf("%d",&a[i]);

 9     scanf("%d %d",&m,&n);

10     for(i=m;i<=n;i++)

11     sum+=a[i];

12     printf("%d\n",sum);

13 return 0;

14 }

15  
View Code

 

E:

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2693&cid=1188

没做出来,C语言不知道该怎么结束这个题意输入循环,,看同学用的C++一个函数能实现,,学习ing

 

F:

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2694&cid=1188

判断输入的数字能有几组有两个至多两位数的数字加起来

196=99+97

196=98+98

196=97+99

共有三组,输出3

 1 #include<stdio.h>

 2 int main()

 3 {

 4     int n,a,b,num;

 5     while(scanf("%d",&n)!=EOF)

 6     {

 7         num=0;

 8         for(a=99;a>=0;a--)

 9         {

10             b=n-a;

11             if(b<=99&&b>=0)

12             num++;

13         }

14         printf("%d\n",num);

15     }

16     return 0;

17 }
View Code

 

 

G

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2695&cid=1188

理解题意不难

两列数字,第一列表示第一次得票的数目,第二列表示第二次得票的数目

先从第一次得票的数目中选出得票最多的K个人,然后按第二次得票的数目求出第二次得票数最多的人的号,即一开始第几个输入的

这里排序时我用了两次结构体的快排,避免超时

 1 #include<stdio.h>

 2 #include<stdlib.h>

 3 #include<string.h>

 4 

 5 struct node

 6 {

 7     int first,second,id;

 8 }num[50005];

 9 

10 int cmp(const void *a,const void *b)

11 {

12     struct node *c=(struct node *)a;

13     struct node *d=(struct node *)b;

14     return d->first-c->first;

15 }

16 

17 int cmp1(const void *a,const void *b)

18 {

19     struct node *c=(struct node *)a;

20     struct node *d=(struct node *)b;

21     return d->second-c->second;

22 }

23 

24 

25 int main()

26 {

27         int m,n,i,win;

28         scanf("%d %d",&m,&n);

29         for(i=0;i<m;i++)

30         {

31             scanf("%d %d",&num[i].first,&num[i].second);

32             num[i].id=i+1;

33         }

34         qsort(num,m,sizeof(struct node),cmp);

35         qsort(num,n,sizeof(struct node),cmp1);

36         printf("%d\n",num[0].id);

37         return 0;

38 }
View Code

 

你可能感兴趣的:(ACM)