Codeforces Round #271 (Div. 2)

A. Keyboard

题意:一个人打字,可能会左偏一位,可能会右偏一位,给出一串字符,求它本来的串

和紫书的破损的键盘一样

 1 #include<iostream>  

 2 #include<cstdio>  

 3 #include<cstring> 

 4 #include <cmath>   

 5 #include<algorithm>  

 6 using namespace std;

 7 

 8 typedef long long LL;

 9 char s[100]="qwertyuiopasdfghjkl;zxcvbnm,./";

10 char a[1005],t[1005];

11 

12 int main()

13 {

14     char ch;

15     int i,j,len;

16     a['L']=1;

17     a['R']=-1;

18     cin>>ch;

19     cin>>t;

20     len=strlen(t);

21     for(i=0;i<len;i++){

22         for(j=0;j<30;j++){

23             if(t[i]==s[j]){

24                 t[i]=s[j+a[ch]];

25                 break;

26             }

27         }            

28     }

29     cout<<t<<"\n";

30 return 0;    

31 }
View Code

 

 

 

B. Worms

题意:给出n,a[1],a[2],a[3]---a[n],第一堆的编号为1到a[i],第二堆的编号为a[1]+1到a[1]+1+a[2],再给出m个数,询问它们分别在哪一堆

把每一堆的起始和结束储存在b[]数组中,再用lower_bound查找

 1 #include<iostream>  

 2 #include<cstdio>  

 3 #include<cstring> 

 4 #include <cmath>   

 5 #include<algorithm>  

 6 using namespace std;

 7 

 8 typedef long long LL;

 9 int a[100005],b[200005];

10 

11 int main()

12 {

13     int n,m,i,j,x,tmp;

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

15     for(i=1;i<=n;i++) scanf("%d",&a[i]);

16     b[1]=1;

17     b[2]=b[1]+a[1]-1;

18     

19     for(i=2;i<=n;i++){

20         b[2*i-1]=b[2*i-2]+1;

21         b[2*i]=b[2*i-1]+a[i]-1;

22     }

23     

24     

25     scanf("%d",&m);

26     while(m--){

27         scanf("%d",&x);

28         tmp=lower_bound(b+1,b+1+2*n,x)-b;

29         printf("%d\n",(tmp+1)/2);

30     }

31   return 0;    

32 }
View Code

 

后来搜CD的题解时,发现有这样做的,将每一个属于哪一堆储存在数组中 感觉有点类似哈希= =

 1 #include<iostream>  

 2 #include<cstdio>  

 3 #include<cstring> 

 4 #include <cmath>   

 5 #include<algorithm>  

 6 using namespace std;

 7 

 8 typedef long long LL;

 9 int vis[1000005];

10 

11 int main()

12 {

13     int n,m,i,j,a,s=0;

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

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

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

17         for(j=0;j<a;j++){

18             s++;

19             vis[s]=i;

20         }

21     }

22     

23     scanf("%d",&m);

24     while(m--){

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



26         printf("%d\n",vis[a]);

27     }

28     return 0;

29 }
View Code

 

 

C. Captain Marmot

题意:给出n个兵团,每个兵团里面有四个点,给出这四个点的起始坐标,旋转中心坐标,问这四个点至少经过多少次旋转能够得到一个正方形

因为一个点只有4种情况,不旋转,旋转90,旋转180,旋转270,

用p[i][j]表示:i表示点的状态,j表示的是这是第几个点。

再4*4*4*4枚举,枚举的时候枚举正方形的边长是否相等,还有对角线长度平方是否为边长平方的2倍

 1 #include<iostream>  

 2 #include<cstdio>  

 3 #include<cstring> 

 4 #include <cmath>   

 5 #include<algorithm>  

 6 using namespace std;

 7 

 8 typedef long long LL;

 9 LL d[10];

10 

11 struct node{

12     int x,y;

13 } p[10][10],center[10];

14 

15 LL dis(node a,node b){

16     return(LL)(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);

17 }

18 

19 void check(){

20     int ans=10005;

21     for(int i=0;i<4;i++)

22     {

23         for(int j=0;j<4;j++)

24         {

25             for(int k=0;k<4;k++)

26             {

27                 for(int l=0;l<4;l++)

28                 {

29                     d[0]=dis(p[i][0],p[j][1]);

30                     d[1]=dis(p[j][1],p[k][2]);

31                     d[2]=dis(p[k][2],p[l][3]);

32                     d[3]=dis(p[l][3],p[i][0]);//正方形的4条直角边 

33                     d[4]=dis(p[i][0],p[k][2]);// 正方形的对角线 

34                     d[5]=dis(p[j][1],p[l][3]);

35                     sort(d,d+6);

36                     if(d[0]==0)

37                         continue;

38                     else

39                         if(d[0]==d[1]&&d[1]==d[2]&&d[2]==d[3]&&d[0]*2==d[4]&&d[4]==d[5])//判断边长和对角线 

40                     {

41                         ans=min(ans,i+j+k+l);

42                         

43                     }

44                 }

45 

46             }

47         }

48     }

49     

50     if(ans!=10005) printf("%d\n",ans);

51     else printf("-1\n");

52 }

53 

54 int main()

55 {

56     int n,j;

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

58     while(n--){

59         for(int i=0;i<4;i++)

60         {

61             cin>>p[0][i].x>>p[0][i].y;

62             cin>>center[i].x>>center[i].y;

63             int xx=p[0][i].x-center[i].x;

64             int yy=p[0][i].y-center[i].y;

65             p[1][i].x=center[i].x-yy;//分别计算出一个点旋转所能够得到的四种状态 

66             p[1][i].y=center[i].y+xx;

67             p[2][i].x=center[i].x-xx;

68             p[2][i].y=center[i].y-yy;

69             p[3][i].x=center[i].x+yy;

70             p[3][i].y=center[i].y-xx;

71         }

72         check();        

73     }

74 return 0;    

75 }
View Code

 

 

 

D. Flowers

题意:给出吃白花必须是k的整数倍,给出吃花朵数的区间 a,b,问满足这样条件的方案数共有多少

dp[i]表示吃到第i朵花的方案数

dp[i]=dp[i-1]+dp[i-k];

 1 #include<iostream>  

 2 #include<cstdio>  

 3 #include<cstring> 

 4 #include <cmath>   

 5 #include<algorithm>  

 6 using namespace std;

 7 

 8 typedef long long LL;

 9 int mod=1e9+7;

10 int dp[100005];

11 

12 int main()

13 {

14     int i,j,t,k,a,b;

15     scanf("%d %d",&t,&k);

16     dp[0]=1;

17     for(i=1;i<=100005;i++){

18         dp[i]=dp[i-1];

19         if(i>=k) dp[i]=(dp[i]+dp[i-k])%mod;

20     }

21     

22     for(i=1;i<=100005;i++){

23         dp[i]=(dp[i]+dp[i-1])%mod;//再求出前缀和 

24     }

25     

26     while(t--){

27         scanf("%d %d",&a,&b);

28     printf("%d\n",((dp[b]-dp[a-1])%mod+mod)%mod);//注意这儿要在括号里面加个mod再mod一次,因为这个挂在了第三个 

29     }

30     return 0;    

31 }
View Code

 

你可能感兴趣的:(codeforces)