ACdream原创群赛(18)のAK's dream题解

只做了4题水题ADGI

A题需要注意的就是“[...]”的输出了,何时输出,何时不输出。

 1 #include <stdio.h>

 2 int main()

 3 {

 4     int n, cur, d;

 5     int cnt = 1;

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

 7     {

 8         printf("Case #%d: ",cnt++);

 9         if(cur==1)

10             printf("[<<]");

11         else

12             printf("(<<)");

13         int start = cur - d;

14         int end = cur + d;

15         if(start >0 && start!=1 && cur!=1)//说明前面有隐藏页,需要输出[...]

16             printf("[...]");

17         for(int i=start; i<=end && i<=n; ++i)

18         {

19             if(i <=0 )

20                 continue;

21             else

22             {

23                 if(i == cur)

24                     printf("[%d]",i);

25                 else

26                     printf("(%d)",i);

27             }

28         }

29         if(end<n && cur!=n)//说明后面有隐藏页,需要输出[...]

30             printf("[...]");

31         if(cur==n)

32             printf("[>>]");

33         else

34             printf("(>>)");

35         printf("\n");

36  

37     }

38 }
View Code

 

D题应该是数学题吧(分步计数原理),将数组weight 和数组pow排序

然后分别判断每个数有多少种选择,然后一一相乘取模
对于第一个hero,如果有a1把剑的weight小于等于power,对于第二个hero,有a2把剑的weight小于等于power,一次类推
那么第一个英雄有a1种选择,第二个英雄有a2-1种选择,第三个英雄有a3-2种选择,一次类推。
至于判断有多少把剑的weight小于每个英雄的power,普通查找会超时,要用二分查找。
二分查找的特性是,对于key,如果数组中有元素与之相等,那么就返回该元素的下标,不然就返回就返回第一个比key大的元素的下标(如果有的话)
如果没有,就返回数组最后一个元素的下标。 所以我们可以用二分查找找出比power[i]小的weight有多少个

 1 #include <stdio.h>

 2 #include <string.h>

 3 #include <algorithm>

 4 using namespace std;

 5 typedef long long LL;

 6 const int N = 100000 + 10;

 7 const int MOD = 1000000007;

 8 int w[N];

 9 int p[N];

10 void input(int &x)

11 {

12     char ch = getchar();

13     while(ch<'0' || ch >'9')

14         ch = getchar();

15     x = 0;

16     while(ch>='0' && ch<='9')

17     {

18         x = x * 10 + ch - '0';

19         ch = getchar();

20     }

21 }

22 int main()

23 {

24     int t;

25     int n;

26     int i,j,k,z;

27     int tCase = 1;

28     input(t);

29     while(t--)

30     {

31         printf("Case #%d: ",tCase++);

32         input(n);

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

34             input(w[i]);

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

36             input(p[i]);

37         sort(w+1, w+n+1);

38         sort(p+1, p+n+1);

39         LL ans = 1;

40         int cnt;

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

42         {

43             cnt = 0;

44             int low = 1; int high = n;

45             int mid;

46             while(low <= high)

47             {

48                  mid = (low + high)/2;

49                 if(p[i] == w[mid])

50                     break;

51                 else if(p[i] >= w[mid])

52                     low = mid + 1;

53                 else

54                     high = mid - 1;

55             }

56             if(p[i] < w[mid])

57                 mid--;

58             ans = (ans*(mid-i+1))%MOD;

59         }

60         printf("%lld\n",ans);

61     }

62 }
View Code

 

G题要没什么,先用字符串读入,判断有没有可能爆,如果有可能,继续进一步的字符串判断,如果没可能,就用sscanf读入,然后判断范围

 1 #include <iostream>

 2 #include <stdio.h>

 3 #include <string>

 4 using namespace std;

 5 typedef long long LL;

 6 string Max = "9223372036854775807";//19

 7 int main()

 8 {

 9     int i;

10     string str;

11     LL num;

12     while(cin>>str)

13     {

14         if(str[0] != '-')  

15         {

16             if(str.size() < 19)

17             {

18                 sscanf(str.c_str(),"%lld",&num);

19                 if(num <= 32767)

20                     puts("short");

21                 else if(num <= 2147483647)

22                     puts("int");

23                 else

24                     puts("long long");

25             }

26             else if(str.size()==19)

27             {

28                 if(str > Max)

29                     puts("It is too big!");

30                 else

31                     puts("long long");

32             }

33             else

34                 puts("It is too big!");

35         }

36         else

37         {

38             if(str.size() < 20)

39             {

40                 sscanf(str.c_str(),"lld",&num);

41                 if(num >= -32767)

42                     puts("short");

43                 else if(num >= 2147483647)

44                     puts("int");

45                 else

46                     puts("long long");

47  

48             }

49             else if(str.size() == 20)

50             {

51                 str.erase(str.begin());

52                 if(str > Max)

53                     puts("It is too big!");

54                 else

55                     puts("long long");

56             }

57             else

58                 puts("It is too big!");

59  

60         }

61     }

62 }
View Code

 

I题要注意的就是最大公约数可能是负数的情况,导致负号出现在分母。应该处理一下再输出。

 1 #include <stdio.h>

 2 const int N = 1000 + 10;

 3 int gcd(int n, int m)

 4 {

 5     if(m == 0)

 6         return n;

 7     return gcd(m,n%m);

 8 }

 9 int main()

10 {

11     int n, i;

12     int coe,exp;

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

14     {

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

16         {

17             scanf("%d%d",&coe,&exp);

18             if( coe % (exp+1)==0)

19                 printf("%d %d ",coe / (exp+1),exp+1);

20             else

21             {

22                 int g = gcd(coe, exp+1);

23                 if(g>0)

24                     printf("%d/%d %d ",coe/g,(exp+1)/g, exp+1);

25                 else

26                     printf("%d/%d %d ",-coe/g,-(exp+1)/g, exp+1);

27      

28             }  

29         }

30         scanf("%d%d",&coe,&exp);

31         if( coe % (exp+1)==0)

32             printf("%d %d\n",coe / (exp+1),exp+1);

33         else

34         {

35             int g = gcd(coe, exp+1);

36             if(g>0)

37                 printf("%d/%d %d\n",coe/g,(exp+1)/g, exp+1);

38             else

39                 printf("%d/%d %d\n",-coe/g,-(exp+1)/g, exp+1);

40         }  

41     }

42 }
View Code

 

J题如果正向模拟,i要不断回溯,导致复杂度时间复杂是O(n*m).但是如果是逆向模拟,i不用回溯,时间复杂度是O(n+m).

 1 #define _CRT_SECURE_NO_DEPRECATE

 2 #include <stdio.h>

 3 #include <string.h>

 4 #include <algorithm>

 5 using namespace std;

 6 const int N = 1000000 + 10;

 7 struct node

 8 {

 9     int val;

10     int index;

11     bool operator<(const node &rhs)const

12     {

13         return val > rhs.val;

14     }

15 }a[N];

16 int hash[N];

17 int ans[N];

18 int op[N];

19 int main()

20 {

21     int t,n,m,tCase = 1,i,j;

22     scanf("%d",&t);

23     while(t--)

24     {

25         memset(hash,0,sizeof(hash));

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

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

28         {

29             scanf("%d",&a[i].val);

30             a[i].index = i;

31         }

32         sort(a,a+n);

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

34             scanf("%d",&op[i]);

35         int cnt = 0;

36         printf("Case #%d: ",tCase++);

37         for(i=0,j=m-1;j>=0;--j)

38         {

39             for(; i<n; ++i)

40             {

41                 if(a[i].val <= op[j])

42                     break;

43                 int index = a[i].index;

44                 hash[index] = true;

45                 if(!hash[index-1] && !hash[index+1])//如果下标的左右都没有被标记过,则该下标自成一块

46                     cnt++;

47                 else if(hash[index-1] && hash[index+1])//因为该下标的加入,导致该下标的左右连在一起,2变1

48                     cnt--;

49             }

50             ans[j] = cnt;

51         }

52         for(i=0; i<m-1; ++i)

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

54         printf("%d\n",ans[m-1]);

55 

56     }

57 }
View Code

 

你可能感兴趣的:(题解)