您的位置:首页 > 其它

暑假N天乐【比赛篇】 —— 2019牛客暑期多校训练营(第六场)

2019-08-09 15:57 459 查看
原文链接:http://www.cnblogs.com/Decray/p/11327795.html

疯狂摸鱼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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: