2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)

http://codeforces.com/contest/1070

 

给你一个d和s,求一个最小的数,使的能整除d,并且每位数的和为s。

如果确定了某n位数取模d的值,那么再计算同样的n位数,取模d也是相同的值时,就多此一举了。比如10%2 == 0  20%2 == 0  同样是两位数,取模2都是等于0。所以取最小的就可以了。

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N = 1e3+10;
 5 struct Nod{
 6     int d, s;
 7     string str;
 8 };
 9 bool vis[N/2][N*5];
10 int d, s;
11 void bfs() {
12     queue<Nod> que;
13     que.push({0,0,""});
14     vis[0][0] = 1;
15     while(que.size()) {
16         Nod nod = que.front();
17         que.pop();
18         if(nod.s > s) continue;
19         if(nod.d == 0 && nod.s == s) {
20             cout << nod.str << endl;
21             return;
22         }
23         for(int i = 0; i < 10; i ++) {
24             int dd = (nod.d*10+i)%d;
25             int ss = nod.s + i;
26             if(!vis[dd][ss]) {
27                 vis[dd][ss] = 1;
28                 que.push({dd,ss,nod.str+char(i+'0')});
29             }
30         }
31     }
32     cout << -1 << endl;
33 }
34 
35 int main() {
36     cin >> d >> s;
37     bfs();
38     return 0;
39 }
View Code

 

D

扔垃圾问题,当天的垃圾可以今天扔也可以明天扔,但最后一天的垃圾必须当天扔。每k个垃圾要用一个垃圾袋。求用垃圾袋最小的数量。

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N = 1e5+10;
 5 
 6 int main() {
 7     ll n, k;
 8     cin >> n >> k;
 9     ll ans = 0, x, pre = 0;
10     for(int i = 1; i <= n; i ++) {
11         cin >> x;
12         if(i == n) {
13             ans += (x+pre+k-1)/k;
14             break;
15         }
16         if(pre > 0) {
17             ans ++;
18             x = max(0LL,x - (k-pre));
19         }
20         ans += x/k;
21         pre = x-x/k*k;
22     }
23     printf("%lld\n",ans);
24     return 0;
25 }
View Code

 

F

有n个观众,每个人有两个由'0'和'1'组成的字符串,还有一个值。从中选取一些观众,使的第一个1的数量和第二个1的数量都不小于一半。

贪心问题,两个1的全部都选上,然后再选取写与01和10组成的,按价值最大的取,最后在去00或01或10 数量不超过11的数量就行。

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N = 4e5+10;
 5 int a[N], b[N], c[N], d[N];
 6 bool cmp(int x, int y) {
 7     return x > y;
 8 }
 9 int main() {
10     int n, x;
11     cin >> n;
12     string s;
13     for(int i = 1; i <= n; i ++) {
14         cin >> s >> x;
15         if(s == "11")  a[++a[0]] = x;
16         else if(s == "10") b[++b[0]] = x;
17         else if(s == "01") c[++c[0]] = x;
18         else d[++d[0]] = x;
19     }
20     sort(a+1,a+1+a[0],cmp);
21     sort(b+1,b+1+b[0],cmp);
22     sort(c+1,c+1+c[0],cmp);
23     ll ans = 0;
24     for(int i = 1; i <= a[0]; i ++) ans += 1LL*a[i];
25     for(int i = 1; i <= min(b[0],c[0]); i ++) ans += 1LL*(b[i]+c[i]);
26     for(int i = min(b[0],c[0])+1; i <= max(b[0],c[0]); i ++) d[++d[0]] = max(b[i],c[i]);
27     sort(d+1,d+1+d[0],cmp);
28     for(int i = 1; i <= min(a[0],d[0]); i ++) ans += 1LL*d[i];
29     printf("%lld\n",ans);
30     return 0;
31 }
View Code

 

H

有n个字符串和q个询问,每次询问有一个字符串s,问这个字符串s是n个字符串中的多少个的子串。

由于n个字符串最多8个字符,它的子串数量最多32个。就预处理一下很好就算出来了。

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N = 1e4+10;
 5 map<string,int> mp1, mp2;
 6 set<string> st;
 7 string s[N];
 8 int main() {
 9     ios::sync_with_stdio(false);
10     cin.tie(0);
11     cout.tie(0);
12     int n, q;
13     cin >> n;
14     string ss;
15     for(int i = 1; i <= n; i ++) {
16         cin >> s[i];
17         st.clear();
18         int len = s[i].length();
19         for(int j = 0; j < len; j ++) {
20             for(int k = 1; k <= len-j; k ++) {
21                 ss = s[i].substr(j,k);
22                 st.insert(ss);
23             }
24         }
25         for(auto tmp : st) {
26             mp1[tmp]++;
27             mp2[tmp] = i;
28             //cout << tmp << endl;
29         }
30     }
31     cin >> q;
32     while(q--) {
33         cin >> ss;
34         if(mp1.count(ss)) {
35             cout << mp1[ss] << ' ' << s[mp2[ss]] << endl;;
36         } else cout << "0 -\n";
37     }
38     return 0;
39 }
View Code

 

k

有n个数,为是否可以分成k份,使的每一份的和都相同。

签到题。

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N = 1e5+10;
 5 int a[N], n, k, sum = 0;
 6 
 7 int find(int x) {
 8     int l = 1, r = n;
 9     while(l <= r) {
10         int m = (l +r)>>1;
11         if(a[m] == x) return m;
12         if(a[m] < x) l = m+1;
13         else r = m - 1;
14     }
15     return -1;
16 }
17 
18 int main() {
19     cin >> n >> k;
20     for(int i = 1; i <= n; i ++) {
21         cin >> a[i];
22         a[i] += a[i-1];        
23     }
24     if(a[n]%k != 0) return 0*printf("No\n");
25     int num = a[n]/k;
26     vector<int> v;
27     for(int i = 1; i <= k; i ++) {
28         int id = find(i*num);
29         if(id == -1) return 0*printf("No\n");
30         v.push_back(id);
31     }
32     printf("Yes\n%d",v[0]);
33     for(int i = 1; i < v.size(); i ++) {
34         printf(" %d",v[i]-v[i-1]);
35     }
36     return 0;
37 }
View Code

 

posted @ 2018-10-23 18:13  starry_sky  阅读(462)  评论(0编辑  收藏  举报