Codeforces Round #578 (Div. 2)

链接: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 }

 

转载于:https://www.cnblogs.com/Carered/p/11345645.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值