暑假N天乐【比赛篇】 —— 2019牛客暑期多校训练营(第六场)
疯狂摸鱼ing...不想写了。
以下题解包括:\(A \ \ \ B \ \ \ C \ \ \ D \ \ \ E \ \ \ G \ \ \ J\)
比赛地址: https://ac.nowcoder.com/acm/contest/886#question
【A】 Garbage Classification 水题
签到题,不说了。
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <bitset> #include <cctype> #include <cstdio> #include <vector> #include <string> #include <cstdlib> #include <cstring> #include <fstream> #include <iomanip> #include <numeric> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const double PI = acos(-1.0); const double eps = 1e-6; const int inf = 0x3f3f3f3f; const int mod = 1e9 + 7; const int maxn = 2000+5; map<char, char> mp; char a[maxn], b[maxn]; int main() { int t, cas = 1; scanf("%d", &t); while(t--) { mp.clear(); scanf("%s%s", a, b); for(int i = 0; i < 26; i++) { mp[i+'a'] = b[i]; } int n = strlen(a); int H = 0, W = 0, D = 0; for(int i = 0; i < n; i++) { if(mp[a[i]] == 'h') { H ++; } else if(mp[a[i]] == 'd') { D ++; } else { W ++; } } printf("Case #%d: ", cas++); if(H*4 >= n) { printf("Harmful\n"); } else if(H*10 <= n) { printf("Recyclable\n"); } else if(D >= 2*W){ printf("Dry\n"); } else { printf("Wet\n"); } } return 0; }
【B】 Shorten IPv6 Address 模拟
给定一个长度 128 位的 01 字符串,按照规则进行变换成16进制的 \(ipv6\) 地址,输出变换后字典序最小的字符串。
纯大模拟,虽然 \(python\) 很好写,但我不会啊。代码是现场敲的,极丑将就看吧。
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <bitset> #include <cctype> #include <cstdio> #include <vector> #include <string> #include <cstdlib> #include <cstring> #include <fstream> #include <iomanip> #include <numeric> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const double PI = acos(-1.0); const double eps = 1e-6; const int inf = 0x3f3f3f3f; const int mod = 1e9 + 7; const int maxn = 1e3+5; char s[maxn]; char str[50][50]; char str_[50][50]; struct node { int l, r; bool operator < (const node& a) const{ if((r-l+1) == (a.r-a.l+1)) { return l > a.l; } return (r-l+1) > (a.r-a.l+1); } }p[50]; int main() { int t, cas=1; scanf("%d", &t); while(t--) { memset(str, '\0', sizeof(str)); memset(str_, '\0', sizeof(str_)); memset(s, '\0', sizeof(s)); int cnt = 0; scanf("%s", s); for(int i = 0; i < 128; i+=16) { char temp[50]; int zzz = 0; for(int j = i; j < i+16; j+=4) { int sum = 0; int x1 = s[j] - '0'; int x2 = s[j+1] - '0'; int x3 = s[j+2] - '0'; int x4 = s[j+3] - '0'; sum = sum + (x1*8 + x2*4 + x3*2 + x4); if(sum >= 10) { temp[zzz++] = 'a'+sum-10; } else { temp[zzz++] = '0'+sum; } } temp[zzz] = '\0'; strcpy(str[cnt++], temp); } for(int i = 0; i < cnt; i++) { int flag = 1; for(int j = 0; j < 4; j++) { if(str[i][j] != '0') { flag = 0; } } // cout << flag << endl; if(flag) { // 全 0 str_[i][0] = '0'; } else { // 去前导 0 int j; for(j = 0; j < 4; j++) { if(str[i][j] != '0') { break; } } for(int k = j; k < 4; k++) { str_[i][k-j] = str[i][k]; } str_[i][4-j] = '\0'; } } int tot = 0; int j = 0; for(int i = 0; i < cnt; i++) { if(strcmp(str_[i], "0") == 0) { for(j = i+1; j < cnt; j++) { if(strcmp(str_[j], "0") != 0) { break; } } p[tot].l = i; p[tot++].r = j-1; } } sort(p, p+tot); p[tot].l = inf; p[tot++].r = 0; char ans[maxn] = {'\0'}; int MIN = inf; for(int k = 0; k < tot; k++) { char tep[maxn] = {'\0'}; int len = p[k].r - p[k].l + 1; int ok = 0; int res = 0; if(len >= 2) { ok = 1; } for(int i = 0; i < cnt; i++) { if(ok == 0) { int m = strlen(str_[i]); for(int j = 0; j < m; j++) { tep[res++] = str_[i][j]; } if(i==cnt-1) { tep[res++] = '\0'; } else { tep[res++] = ':'; } } else { if(p[k].l == i) { if(i == 0) { tep[res++] = ':'; tep[res++] = ':'; } else { tep[res++] = ':'; } i = p[k].r; if(i == cnt-1) { tep[res++] = '\0'; } continue; } int m = strlen(str_[i]); for(int j = 0; j < m; j++) { tep[res++] = str_[i][j]; } if(i==cnt-1) { tep[res++] = '\0'; } else { tep[res++] = ':'; } } } if(res < MIN) { strcpy(ans, tep); MIN = res; } else if(res == MIN) { if(strcmp(ans, tep) > 0) { strcpy(ans, tep); } } } printf("Case #%d: ", cas++); printf("%s\n", ans); } return 0; }
【C】 Palindrome Mouse 回文自动机
回文自动机套模板。
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <bitset> #include <cctype> #include <cstdio> #include <vector> #include <string> #include <cstdlib> #include <cstring> #include <fstream> #include <iomanip> #include <numeric> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const double PI = acos(-1.0); const double eps = 1e-6; const int inf = 0x3f3f3f3f; const int mod = 1e9 + 7; const int maxn = 100005; const int N = 26; ll ans, res; struct Palindromic_Tree { int nxt[maxn] ; // next指针,next指针和字典树类似,指向的串为当前串两端加上同一个字符构成 int fail[maxn]; // fail指针,失配后跳转到fail指针指向的节点 ll cnt[maxn]; // 表示节点i表示的本质不同的串的个数(建树时求出的不是完全的,最后count()函数跑一遍以后才是正确的) int num[maxn]; // 表示以节点i表示的最长回文串的最右端点为回文串结尾的回文串个数 int len[maxn]; // len[i]表示节点i表示的回文串的长度(一个节点表示一个回文串) int S[maxn]; // 存放添加的字符 int last; // 指向新添加一个字母后所形成的最长回文串表示的节点。 int n; // 表示添加的字符个数。 int p; // 表示添加的节点个数。 int vis[maxn]; int newnode(int l) {// 新建节点 for(int i = 0; i < N; ++i) nxt[i] = 0; cnt[p] = 0; num[p] = 0; len[p] = l; vis[p] = 0; return p++; } void init() { // 初始化 p = 0; newnode(0); newnode(-1); last = 0; n = 0; S = -1; // 开头放一个字符集中没有的字符,减少特判 fail[0] = 1; } int get_fail(int x) { // 和KMP一样,失配后找一个尽量最长的 while(S[n-len[x]-1] != S ) x = fail[x]; return x; } void add(int c) { c -= 'a'; S[++n] = c; int cur = get_fail(last); // 通过上一个回文串找这个回文串的匹配位置 if(!nxt[cur][c]) { // 如果这个回文串没有出现过,说明出现了一个新的本质不同的回文串 int now = newnode(len[cur]+2); // 新建节点 fail[now] = nxt[get_fail(fail[cur])][c]; // 和AC自动机一样建立fail指针,以便失配后跳转 nxt[cur][c] = now; num[now] = num[fail[now]] + 1; } last = nxt[cur][c]; cnt[last] ++; } void dfs(int x) { stack<int> s; int y = fail[x]; while(y > 1 && vis[y] == 0) { res ++; s.push(y); vis[y] = 1; y = fail[y]; } if(x > 1) { ans += res; vis[x] = 1; res ++; } for(int i = 0; i < 26; i++) { if(nxt[x][i]) { dfs(nxt[x][i]); } } if(x > 1) { vis[x] = 0; res --; } y = x; while(!s.empty()) { res --; vis[s.top()] = 0; s.pop(); } } }T; int main() { string a; int t; int cas = 1; cin >> t; while(t--) { cin >> a; T.init(); int len = a.size(); for(int i = 0; i < len; i++) T.add(a[i]); res = ans = 0; T.dfs(0); T.dfs(1); cout << "Case #" << cas++ << ": "; cout << ans << endl; } }
【D】 Move 思维/二分
[p]虽然是数据水所以二分过了,但是我懒得写正解,就这样。#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <bitset> #include <cctype> #include <cstdio> #include <vector> #include <string> #include <cstdlib> #include <cstring> #include <fstream> #include <iomanip> #include <numeric> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const double PI = acos(-1.0); const double eps = 1e-6; const int inf = 0x3f3f3f3f; const int mod = 1e9 + 7; const int maxn = 1e3+5; int n, k; int a[maxn]; int sk[maxn]; multiset<int> s; int solve(int x) { multiset<int> temp; temp = s; for(int i = 1; i <= k; i++) { int sum = x; while(sum>0) { auto it = temp.upper_bound(sum); if(it == temp.begin()) { break; } it--; sum -= (*it); temp.erase(it); } if(temp.size() == 0) { return 1; } } return 0; } int main() { int t, cas = 1; scanf("%d", &t); while(t--) { s.clear(); scanf("%d%d", &n, &k); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); s.insert(a[i]); } int l = 1, r = 1000*1000+5; int ans = 1; while(l <= r) { int mid = (l+r) >> 1; int res = solve(mid); if(res == 1) { ans = mid; r = mid-1; } else { l = mid+1; } } for(int i = max(0, ans-100); i <= ans; i++) { if(solve(i)) { printf("Case #%d: ", cas++); printf("%d\n", i); break; } } } return 0; }
【E】 Androgynos 构造
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <bitset> #include <cctype> #include <cstdio> #include <vector> #include <string> #include <cstdlib> #include <cstring> #include <fstream> #include <iomanip> #include <numeric> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const double PI = acos(-1.0); const double eps = 1e-6; const int inf = 0x3f3f3f3f; const int mod = 1e9 + 7; const int maxn = 2e3+5; int mp[maxn][maxn]; int ans[maxn]; int n; int main() { int t, cas = 1; scanf("%d", &t); while(t--) { scanf("%d", &n); printf("Case #%d: ", cas++); if(n % 4 != 0 && n % 4 != 1) { printf("No\n"); } else { printf("Yes\n"); int k = n / 4; memset(mp, 0, sizeof(mp)); /* 团 1 独立集 2 独立集 3 团 4 */ // 团 1 内部 for(int i = 1; i <= k; i++) { for(int j = 1; j <= k; j++) { if(i != j) { mp[i][j] = mp[j][i] = 1; } } } // 团 1 --> 独立集 2 for(int i = 1; i <= k; i++) { for(int j = k+1; j <= 2*k; j++) { mp[i][j] = mp[j][i] = 1; } } // 独立集 2 --> 独立集 3 for(int i = k+1; i <= 2*k; i++) { for(int j = 2*k+1; j <= 3*k; j++) { mp[i][j] = mp[j][i] = 1; } } // 独立集 3 --> 团 4 for(int i = 2*k+1; i <= 3*k; i++) { for(int j = 3*k+1; j <= 4*k; j++) { mp[i][j] = mp[j][i] = 1; } } // 团 4 内部 for(int i = 3*k+1; i <= 4*k; i++) { for(int j = 3*k+1; j <= 4*k; j++) { if(i != j) { mp[i][j] = mp[j][i] = 1; } } } // 1 2 3 4 ---> ans[i] = 2 4 1 3 for(int i = 1; i <= k; i++) { ans[i] = i+k; ans[i+k] = i+3*k; ans[i+2*k] = i; ans[i+3*k] = i+2*k; } // 多出来的点连向两个团 1 4 即可 if(n % 4 == 1) { for(int i = 1; i <= k; i++) { mp[i] = mp [i] = 1; } for(int i = 3*k+1; i <= 4*k; i++) { mp[i] = mp [i] = 1; } ans = n; } for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { printf("%d", mp[i][j]); } printf("\n"); } for(int i = 1; i <= n; i++) { printf("%d%c", ans[i], i==n?'\n':' '); } } } return 0; }
【G】 Is Today Friday? 暴力
#include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <bitset> #include <cctype> #include <cstdio> #include <vector> #include <string> #include <cstdlib> #include <cstring> #include <fstream> #include <iomanip> #include <numeric> #include <iostream> #include <algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const double PI = acos(-1.0); const double eps = 1e-6; const int inf = 0x3f3f3f3f; const int mod = 1e9 + 7; const int maxn = 1e5+5; int n; string str[maxn]; int ord[10]; int check(int x) { int year = ord[str[x][0]-'A']*1000 + ord[str[x][1]-'A']*100 + ord[str[x][2]-'A']*10 + ord[str[x][3]-'A']; int month = ord[str[x][5]-'A']*10 + ord[str[x][6]-'A']; int day = ord[str[x][8]-'A']*10 + ord[str[x][9]-'A']; int d_max; if(month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) { d_max = 31; } else if(month==4 || month==6 || month==9 || month==11) { d_max = 30; } else if(month==2 && ((year%4==0 && year%100!=0) || year%400==0)) { d_max = 29; } else { d_max = 28; } if(year<1600 || year>9999 || month<1 || month>12 || day<1 || day>d_max) { return 0; } if(month==1 || month==2) { year--; month += 12; } int w = (day + 2*month + 3*(month+1)/5 + year + year/4 - year/100 + year/400) % 7 + 1; if(w == 5) { return 1; } return 0; } int main() { int t, cas = 1; scanf("%d", &t); while(t--) { for(int i = 0; i < 10; i++) { ord[i] = i; } scanf("%d", &n); for(int i = 1; i <= n; i++) { cin >> str[i]; } sort(str+1, str+1+n); n = unique(str+1, str+1+n) - (str+1); int ok = 0; do { ok = 1; for(int i = 1; i <= n; i++) { if(check(i) == 0) { ok = 0; break; } } if(ok) { break; } }while(next_permutation(ord, ord+10)); printf("Case #%d: ", cas++); if(ok == 0) { printf("Impossible\n"); } else { for(int i = 0; i < 10; i++) { printf("%d", ord[i]); } printf("\n"); } } return 0; }
【J】 Upgrading Technology 贪心
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; const int maxn=1019; const ll INF = 1ll*(1e9)*(1e5); ll a[maxn][maxn],d[maxn]; ll pre[maxn][maxn]; ll P[maxn]; ll tail[maxn]; int n,m; ll minn; ll ans1,ans2,minj; int main(){ int T; scanf("%d",&T); int kase=1; while(T--){ scanf("%d%d",&n,&m); memset(pre,0,sizeof(pre)); memset(P,0,sizeof(P)); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ scanf("%lld",&a[i][j]); } } for(int i=1;i<=m;i++){ scanf("%lld",&d[i]); } for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ P[i]-=a[j][i]; } P[i]=P[i-1]+P[i]+d[i]; } memset(tail,0,sizeof(tail)); //tail ! ll ans=P[m]; for(int i=m-1;i>=0;i--){ int flag=0;minn=-INF; for(int j=1;j<=n;j++){ if(tail[j]+a[j][i+1]<=0){ tail[j]+=a[j][i+1]; P[i]-=tail[j]; if(minn<=tail[j]){ minn=tail[j]; minj=j; } } else{ tail[j]=0; flag=1; } } if(!flag){ tail[minj]=0; P[i]+=minn; } ans=max(ans,P[i]); } if(ans<0) ans=0; printf("Case #%d: %lld\n",kase++,ans); } }
转载于:https://www.cnblogs.com/Decray/p/11327795.html
- 暑假N天乐【比赛篇】 —— 2019牛客暑期多校训练营(第二场)
- 暑假N天乐【比赛篇】 —— 2019牛客暑期多校训练营(第一场)
- 2019牛客暑期多校训练营(第六场)A Garbage Classification
- 2019牛客暑期多校训练营(第六场)
- 2019牛客暑期多校训练营(第六场)D Move 二分
- 2019牛客暑期多校训练营(第六场)J(枚举)
- 2019牛客暑期多校训练营(第一场) - E - ABBA - 贪心 - dp - 组合
- 2019牛客暑期多校训练营(第一场)J-Fraction Comparision
- 2019牛客暑期多校训练营(第四场)I string —— 后缀自动机+回文自动机
- 2019牛客暑期多校训练营(第四场)D triples I
- 2019牛客暑期多校训练营(第九场) E.All men are brothers
- 2019牛客暑期多校训练营(第四场)K number
- 2019牛客暑期多校训练营(第五场)H subsequence 2(拓扑排序)
- 2019牛客暑期多校训练营(第二场场)_H题Second Large Rectangle
- 2019牛客暑期多校训练营(第八场)A All-one Matrices(单调栈,01矩阵)
- 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)
- 2019牛客暑期多校训练营(第四场) K题 number
- 2019 牛客暑期多校训练营(第四场)J Free
- 2019牛客暑期多校训练营 第五场
- 2019牛客暑期多校训练营(第五场)G(DP)