Codeforces #398 (2) B 模拟 C dfs D 贪心,双指针 E 贪心,思维
Codeforces Round #398 (Div. 2)
题意:护照处工件时间 ts 到 tf-1,已知有n个人各自会在 ti 时间到那排队,每人处理时间 t。Vasya想花最少时间排队,问他什么时间到那最好。
tags:骚到炸的题,很多坑,有时间再做一遍
//B #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define FF(i,a,b) for (int i=a;i<=b;i++) #define F(i,b,a) for (int i=b;i>=a;i--) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 2e5+10; const ll inf = 1e18; ll ts, tf, t0, t1, t2, t[N], minn=inf, mi; int n; int main() { scanf("%lld %lld %lld %d", &ts, &tf, &t0, &n); t1=ts; FF(i,1,n) scanf("%lld", &t[i]); FF(i,1,n) { t2=max(t[i], max(ts, t1)); if(t1<t2) return 0*printf("%lld\n", t1); t1=t2+t0; if(t2+t0-1>=tf) break; if(i!=n && t[i+1]-1>=t[i] && t2+t0-(t[i+1]-1)<minn && t2+t0*2-1<tf) minn=t2+t0-(t[i+1]-1), mi=t[i+1]-1; } if(t1+t0-1<tf) return 0*printf("%lld\n", t1); if(t[1]-1>=0 && ts-(t[1]-1)<minn) printf("%lld\n", t[1]-1); else printf("%lld\n", mi); return 0; }
题意:一个灯泡树,每个灯泡有一个温度 ti,要把这个灯泡树分成温度和相同的3部分,求在哪两条边断掉。
tags:dfs求出每个子树的Size,在dfs的过程中进行判断。因为温度可正可负,也有很多坑==
#include<bits/stdc++.h> using namespace std; //#pragma comment(linker, "/STACK:102400000,102400000") #define FF(i,a,b) for (int i=a;i<=b;i++) #define F(i,b,a) for (int i=b;i>=a;i--) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 2e6+10; int n, t[N], p, Size[N], ro, head[N], tot, sum, ans[3], cnt; struct Edge{int to,next;}e[N]; void Addedge(int u,int v) { e[++tot].to=v, e[tot].next=head[u], head[u]=tot; } void dfs(int u, int fa) { Size[u]=t[u]; for(int i=head[u]; i; i=e[i].next) { int v=e[i].to; if(v!=fa) { dfs(v, u); Size[u]+=Size[v]; } } if(Size[u]==sum && u!=ro) { ans[++cnt]=u; Size[u]=0; if(cnt==2) printf("%d %d\n", ans[1], ans[2]), exit(0); } } int main() { scanf("%d", &n); FF(i,1,n) { scanf("%d %d", &p, &t[i]); Addedge(p, i), Addedge(i, p); if(p==0) ro=i; sum+=t[i]; } if(sum%3) return 0*puts("-1"); sum/=3; dfs(ro, 0); puts("-1"); return 0; }
题意:冰箱里有n瓶牛奶,各有一个最后可饮用日期 fi;超市有m瓶牛奶,各有一个最后可饮用日期 si。Olya每天喝k瓶牛奶(如果没有k瓶就全部喝掉),Olya还可以到超市买牛奶。问Olya是否可以不浪费一瓶牛奶,如果可以,求Olya最多可以在超市买入多少瓶牛奶,并输出买入牛奶的编号。
tags:只要从后面往前贪心就好。对于冰箱里的一瓶牛奶 i:如 fi>k,则(fi-k)瓶要放在前面喝掉;如 fi<k,则最多可以买入(k-fi)瓶 i 日期后的牛奶。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define FF(i,a,b) for (int i=a;i<=b;i++) #define F(i,b,a) for (int i=b;i>=a;i--) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 1e7+10; int n, m, k, f[N], x, t1, t2, ans[N], cnt; struct S{int id, v;}s[N]; bool cmp(S a, S b) { return a.v<b.v; } int main() { scanf("%d %d %d", &n, &m, &k); FF(i,1,n) scanf("%d", &x), f[x]++; FF(i,1,m) scanf("%d", &s[i].v), s[i].id=i; t2=m; sort(s+1, s+1+m,cmp); F(i,N-1,0) { if(f[i]>k) { x=f[i]-k, t1=i-1; while(true) { if(t1<0) return 0*puts("-1"); if(f[t1]<k) { if(k-f[t1]>=x) f[t1]+=x, x=0; else x-=(k-f[t1]), f[t1]=k; } if(x>0) t1--; else break; } f[i]=k; } else if(f[i]<k) { if(s[t2].v>=i) { x=k-f[i]; while(true) { if(t2<=0 || s[t2].v<i || x<=0) break; ans[++cnt]=s[t2].id, s[t2].v=-1, x--, f[i]++; t2--; } } } } printf("%d\n", cnt); FF(i,1,cnt) printf("%d ", ans[i]); puts(""); return 0; }
题意:有两种货币:1元的硬币,100元的纸钞。Arseny有m个硬币,无穷多张纸钞。在未来的n天,他每天要花 ci元。收银员如果要找回 x元给Arseny,收银员的不开心值增加 x*w[i]。问Arseny每一天要怎么付款,使得最后收银员不开心值最小。
tags:有点考思维== 每一天付 ci元,关键就是 ci%100是要直接给硬币还是让收银员找。假设到了第 i 天,这 i 天先全部都直接给硬币,如果硬币数不够了,那说明前面 i 天就必须要有找回硬币的情况。到这里就是贪心了,找前面增加不开心值最少的一天,让这一天找回硬币。
#include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define FF(i,a,b) for (int i=a;i<=b;i++) #define F(i,b,a) for (int i=b;i>=a;i--) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f typedef long long ll; const int N = 2e5+10; ll n, m, c[N], w[N], ans, ci; bool flag[N]; priority_queue<pair<ll, int > >Q; int main() { scanf("%lld %lld", &n, &m); FF(i,1,n) scanf("%lld", &c[i]); FF(i,1,n) scanf("%lld", &w[i]); FF(i,1,n) { ci=c[i]%100; if(ci==0) continue; Q.push({-(100-ci)*w[i], i}); m-=ci; while(m<0) { int id=Q.top().second; ans+=(-Q.top().first); flag[id]=1; Q.pop(); m+=100; } } printf("%lld\n", ans); FF(i,1,n) printf("%lld %lld\n", c[i]/100+flag[i], flag[i]?0LL:c[i]%100); return 0; }