链接:http://codeforces.com/contest/1200
A. Hotelier
题意:0 - 9号房间,客人可以从左边进,也可以从右边进,有空位就入住,L代表从左边进,R代表从右边进,0-9代表该房间的客人离开退房。问最终10个房间状态。
思路:直接标记模拟,不难的题愣了好久结果还被hack了 真气人。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn =1e5 + 5; 4 int vis[101]; 5 int room[101]; 6 int main() 7 { 8 std::ios::sync_with_stdio(false); 9 int n; 10 string s; 11 cin >> n >> s; 12 int t; 13 int st = 0, ed = 9; 14 for(int i = 0;i < n;i++) 15 { 16 if(s[i] == 'L') 17 { 18 bool flag = true; 19 for(int j = 0;j <= 9;j++) 20 { 21 if(vis[j] || !room[j]) 22 { 23 room[j] = 1,vis[j] = 0; 24 flag = false; 25 break; 26 } 27 } 28 if(flag) 29 room[st++] = 1; 30 } 31 if(s[i] == 'R') 32 { 33 bool flag = true; 34 for(int j = 9;j >= 0;j--) 35 { 36 if(vis[j] || !room[j]) 37 { 38 room[j] = 1,vis[j] = 0; 39 flag = false; 40 break; 41 } 42 } 43 if(flag) 44 room[ed--] = 1; 45 } 46 if(s[i] >= '0' && s[i] <= '9') 47 { 48 t = s[i] - '0'; 49 vis[t] = 1; 50 room[t] = 0; 51 } 52 } 53 for(int i = 0;i < 10;i++) 54 { 55 cout << room[i]; 56 } 57 cout << endl; 58 return 0; 59 }
B - Block Adventure
题意:跳格子,从1跳到n,每个格子有高度,你站在这个格子上可以用背包里的方块使自己变高,也可以拿走自己脚下的方块让自己变低,当和下一个格子的高度差不超过k就能跳,背包容量无限,问能否走到N。
思路:每次走都贪心,距离不够就用格子垫,够了就尽量收取最多的格子为后面做准备,。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn =500; 4 long long h[maxn]; 5 int main() 6 { 7 std::ios::sync_with_stdio(false); 8 int t; 9 cin >> t; 10 while(t--) 11 { 12 int n; 13 long long m, k; 14 cin >> n >> m >> k; 15 for(int i = 1;i <= n;i++) 16 { 17 cin >> h[i]; 18 } 19 int i; 20 for(i = 1;i < n;i++) 21 { 22 if(h[i] > h[i + 1]) 23 m += h[i] - h[i + 1],h[i] = h[i + 1]; 24 long long t = h[i+1] - h[i]; 25 if(t <= k) m += min(k - t,h[i]); 26 else{ 27 if(m >= t - k) m -= (t - k); 28 else{ 29 break; 30 } 31 } 32 } 33 if(i == n) cout << "YES" << endl; 34 else cout << "NO" << endl; 35 } 36 return 0; 37 }
C. Round Corridor
题意:有两个盘,内盘分为n份,外盘分为m份,然后问你能否从询问的sy走到ey;
思路:想到是gcd的,发现不会写orz,还是看了别人的代码才发现自己真蠢。
AC代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 int main() 5 { 6 ll n, m; 7 ll t; 8 cin >> n >> m >> t; 9 ll d = __gcd(n, m); 10 ll x = n / d; 11 ll y = m / d; 12 while(t--) 13 { 14 ll sx, sy, ex, ey; 15 cin >> sx >> sy >> ex >> ey; 16 sy--,ey--; 17 if(sx == 1)sy /= x; 18 else sy /= y; 19 20 if(ex == 1)ey /= x; 21 else ey /= y; 22 23 if(sy == ey) cout << "YES" << endl; 24 else cout << "NO" << endl; 25 } 26 return 0; 27 }
D. White Lines
待补
E. Compress Words
题意:给你n个字符串 合成一个,如果前后缀有一样的,就合并。
思路:看题解发现有用KMP匹配,于是花了点时间学了下KMP还真不难。
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e6 + 5; 4 int Next[maxn]; 5 char s[maxn], t[maxn]; 6 int tlen, slen; 7 void getNext() 8 { 9 int j = 0; 10 int k = -1; 11 Next[0] = -1; 12 while(j < tlen) 13 { 14 if(k == -1 || t[j] == t[k]) 15 { 16 Next[++j] = ++ k; 17 if(t[j] != t[k]) 18 Next[j] = k; 19 } 20 else k = Next[k]; 21 } 22 } 23 int KMP() 24 { 25 int i = max(slen - tlen, 0); 26 getNext(); 27 int j = 0; 28 while(i < slen && j < tlen) 29 { 30 if(j == -1 || s[i] == t[j]) 31 { 32 i++,j++; 33 } 34 else j = Next[j]; 35 } 36 return j; 37 } 38 int main() 39 { 40 int n ; 41 scanf("%d",&n); 42 scanf("%s",s); 43 slen = strlen(s); 44 for(int i = 1;i < n;i++) 45 { 46 scanf("%s",t); 47 tlen = strlen(t); 48 int pos = KMP(); 49 for(int j = pos;j < tlen;j++) 50 { 51 s[slen] = t[j]; 52 slen++; 53 } 54 } 55 printf("%s",s); 56 return 0; 57 }