Educational Codeforces Round 29

A. Quasi-palindrome

题目链接:http://codeforces.com/contest/863/problem/A

题目意思:问一个数可不可以在不上一些前缀0以后变成一个回文数。

题目思路:暴力减掉后缀0,然后把剩余的部分暴力看一下是不是回文,如果是回文说明yes,否则no

代码:

 1 //Author: xiaowuga
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 #define inf 0x3f3f3f3f
 5 #define MAX INT_MAX
 6 #define mem(s,ch) memset(s,ch,sizeof(s))
 7 const long long N=100000; 
 8 const long long mod=1e9+7; 
 9 typedef long long LL;
10 typedef int II;
11 typedef unsigned long long ull;
12 #define nc cout<<"nc"<<endl
13 #define endl "\n"
14 int main() {
15     ios::sync_with_stdio(false);cin.tie(0);
16     char s[20];
17     cin>>s;
18     II len=strlen(s);
19     II r=len-1;
20     for(II i=len-1;i>=0;i--){
21         if(s[i]=='0') r--; 
22         else break;
23     }
24     for(II i=0,j=r;i<=j;i++,j--){
25         if(s[i]!=s[j]){
26             cout<<"NO"<<endl;
27             return 0;
28         } 
29     }
30     cout<<"YES"<<endl;
31     return 0;
32 }
View Code

B. Kayaking

题目链接:http://codeforces.com/contest/863/problem/B

题目意思:现在有2n个人,n-1个可以装两个人的小皮艇,和两个只能装一个人的小皮艇,装两人的小船,如果两个人体重差太大,翻船值比较高,翻船值就是他们的绝对值,求最小的翻船值总和。

题目思路:我们考虑到n最大只有五十,所以我们可以暴力枚举挑出两个人去做一个人的小皮艇,然后剩下的人求翻船值,在这之前我们需要先排序。

代码:

 1 /* ***********************************************
 2 Author        :xiaowuga
 3 Created Time  :2017年09月30日 星期六 22时39分17秒
 4 File Name     :Kayaking.cpp
 5 ************************************************ */
 6 #include <bits/stdc++.h>
 7 #define mem(s,ch) memset(s,ch,sizeof(s))
 8 typedef long long LL; 
 9 #define inf 0x3f3f3f3f 
10 const long long N=1000000;
11 const long long mod=1e9+7;
12 using namespace std;
13 int main(){
14     ios::sync_with_stdio(false);cin.tie(0);
15     int n;
16     int a[100];
17     cin>>n;
18     n*=2;
19     for(int i=0;i<n;i++) cin>>a[i];
20     sort(a,a+n);
21     int ans=inf;
22     for(int i=0;i<n-1;i++){
23         for(int j=i+1;j<n;j++){
24             int sum=0,t=-1;    
25             for(int k=0;k<n;k++){
26                 if(k==i||k==j) continue;
27                 sum+=a[k]*t;
28                 t*=-1;
29             }
30             ans=min(ans,sum);
31         }
32     }
33     cout<<ans<<endl;
34     return 0;
35 }
View Code

C. 1-2-3

题目意思:现在有两个机器人做类似石头剪刀布的游戏,(1打败3,3打败2,2打败1)现在给出k,a,b,三个数以及两个3*3的矩阵我们设其中一个为A,另一个为B,k表示比赛k轮,a,b表示两个机器人第一场出的数,两个矩阵表示,加入上一场两个机器人出了a,b,那么这一场,两个机器人会分别出A[a][b]和B[a][b],问k轮以后各自赢了多少局。

题目思路:首先这个肯定是会存在循环节的,而且循环节不会太长,估计最多也就十几,我们可以先求出循环节长度,找到完整的循环节数量,每个循环节中两个机器人各自赢的数量,和开始进入完整循环节前那一小部分的胜负情况,以及剩余的不满一个完整循环节的胜负情况。然后加在一块就对了,唯一注意的就是很有可能k小于进入进入完整循环节的次数,需要特判一下。

题目链接:http://codeforces.com/contest/863/problem/C

代码:

 1 /* ***********************************************
 2 Author        :xiaowuga
 3 Created Time  :2017年10月01日 星期日 01时32分10秒
 4 File Name     :C.1-2-3.cpp
 5 ************************************************ */
 6 #include <bits/stdc++.h>
 7 #define mem(s,ch) memset(s,ch,sizeof(s))
 8 typedef long long LL; 
 9 #define inf 0x3f3f3f3f 
10 const long long N=1000000;
11 const long long mod=1e9+7;
12 using namespace std;
13 int A[4][4],B[4][4];
14 int vis[4][4]={0};
15 int ct[50][2]={0};
16 int win[50]={0};
17 int main(){
18     ios::sync_with_stdio(false);cin.tie(0);
19     LL k;
20     int a,b;
21     cin>>k>>a>>b;
22     for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) cin>>A[i][j];    
23     for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) cin>>B[i][j];    
24     int c=0;
25     int ta=a,tb=b,x,y;
26     vector<pair<int,int> >q;
27     while(1){
28         c++;
29         if(vis[ta][tb]) break;
30         vis[ta][tb]=c;
31         q.push_back(make_pair(ta,tb));
32         x=ta;y=tb;
33         ta=A[x][y];
34         tb=B[x][y];
35     }    
36     int cir=c-vis[ta][tb];
37     int lim=vis[ta][tb];
38     LL ansa=0,ansb=0;    
39     if(k<lim){
40         for(int i=0;i<k;i++){
41             x=q[i].first;y=q[i].second;
42             if(x==y) continue;
43             else if((x==3&&y==2)||(x==2&&y==1)||(x==1&&y==3)) ansa++;
44             else ansb++;
45         }
46         cout<<ansa<<' '<<ansb<<endl;
47         return 0;
48     }
49     for(int i=0;i<lim-1;i++){
50         x=q[i].first;y=q[i].second;
51         if(x==y) continue;
52         else if((x==3&&y==2)||(x==2&&y==1)||(x==1&&y==3)) ansa++;
53         else ansb++;
54     }
55     vector<pair<int,int> >p;
56     int cta=0,ctb=0;
57     for(int i=lim-1;i<q.size();i++){
58         x=q[i].first;y=q[i].second;
59         p.push_back(make_pair(x,y));
60         if(x==y) continue;
61         else if((x==3&&y==2)||(x==2&&y==1)||(x==1&&y==3)) cta++;
62         else ctb++;
63     }
64     LL t=(k-lim+1)/cir,l=(k-lim+1)%cir;    
65     ansa+=t*cta;ansb+=t*ctb;
66     for(int i=0;i<l;i++){
67         x=p[i].first;y=p[i].second;
68         if(x==y) continue;
69         else if((x==3&&y==2)||(x==2&&y==1)||(x==1&&y==3)) ansa++;
70         else ansb++;
71     }
72     cout<<ansa<<' '<<ansb<<endl;
73     return 0;
74 }
View Code

D. Yet Another Array Queries Problem

题目链接:http://codeforces.com/contest/863/problem/D

题目意思:现在给一个数列,包含n个数,然后将要进行q次操作,q次操作之后进行m次询问,每次询问给予一个下标询问进行q此操作以后该下标位置的值是多少?

操作有两种:

1.比如12345 ,1-3轮转,变成23145,每个数变成自己右边的数,右边界的数,变成左边界的数。

2.区间翻转

题目思路:我们观察到m的数量是比较少,我们我们考虑反向推倒,找出这个下标在q次操作之前的下标是多少,就可以直接在原数组里面查询了,所以最大mq的复杂度就可以解决问题,观察数据我们发现这个复杂度是可行的。

代码:

 1 /* ***********************************************
 2 Author        :xiaowuga
 3 Created Time  :2017年10月02日 星期一 09时12分59秒
 4 File Name     :text.cpp
 5 ************************************************ */
 6 #include <bits/stdc++.h>
 7 #define mem(s,ch) memset(s,ch,sizeof(s))
 8 typedef long long LL; 
 9 #define inf 0x3f3f3f3f 
10 #define second r
11 #define first l
12 const long long N=1000000;
13 const long long mod=1e9+7;
14 using namespace std;
15 struct node{
16     int l,r,id;
17     bool operator <(const node &m) const{
18         return l==r?r<m.r:l<m.l;
19     }
20 }tv[N];
21 int main(){
22     ios::sync_with_stdio(false);cin.tie(0);
23     int n;
24     cin>>n;
25     for(int i=1;i<=n;i++){
26         cin>>tv[i].l>>tv[i].r;    
27         tv[i].id=i;
28     }    
29     sort(tv+1,tv+1+n);
30     for(int i=2;i<=n;i++){
31         if(tv[i].r<=tv[i-1].r){
32             cout<<tv[i].id<<endl;
33             return 0;
34         }
35         else if(tv[i].l<=tv[i-1].l){
36             cout<<tv[i-1].id<<endl;    
37             return 0;
38         }
39         tv[i].l=max(tv[i].l,tv[i-1].r+1);
40     }
41     cout<<-1<<endl;
42     return 0;
43 }
View Code

 

posted on 2017-10-03 00:04  xiaowuga  阅读(189)  评论(0编辑  收藏  举报

导航