首页 > 代码库 > Codeforces Round #257 (Div. 2) A/B/C/D
Codeforces Round #257 (Div. 2) A/B/C/D
前三题早就写好了,一直在纠结D
A. Jzzhu and Children
题意:就是简单的模拟,给排成一队的孩子分发糖果,每个孩子有至少要得到的糖果数。
然后每次给队头的孩子分发m个糖果,如果他已经得到了足够的糖果(大于等于他想得到的
最少糖果数)那么他就出队,否则他就去队尾。问最后一个孩子的编号。
算法:队列模拟,水题~
#include<cstdio> #include<iostream> #include<cstring> #include<queue> using namespace std; struct node { int v,id; }; queue<node> q; int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { while(!q.empty()) q.pop(); node cur; for(int i=1;i<=n;i++) { scanf("%d",&cur.v); cur.id = i; q.push(cur); } int flag = 0; while(!q.empty()) { if(q.size()==1) flag = 1; node x,next; x = q.front(); q.pop(); if(flag==1) { printf("%d\n",x.id); break; } int t = x.v-m; if(t>0) { next.v = t; next.id = x.id; q.push(next); } } } return 0; }
B. Jzzhu and Sequences
题意: 现在输入x和y,求fn%1000000007(109?+?7)。
算法:
就是找到一个循环节
f(i) = f(i-1) - f(i-2)
f(i+1) = -f(i-2)
f(i+2) = -f(i-1)
f(i+3) = f(i-2) - f(i-1)
f(i+4) = f(i-2)
f(i+5) = f(i-1)
f(i+6) = f(i-1) - f(i-2) = f(i)
以6为一个循环周期。
注意输入x 和 y 时就要处理>mod则 %mod,小于mod 则+mod后再模mod。避免后面溢出。
注意n = 1 和2 的时候直接输出。
#include<cstdio> #include<cstring> #include<iostream> using namespace std; typedef long long ll; const ll mod = 1000000007LL ; ll a[10]; ll f1,f2,n; int main() { while(scanf("%I64d%I64d",&f1,&f2)!=EOF) { scanf("%I64d",&n); int x = 0; if(f1>mod) f1%=mod; if(f1<0) f1 = (f1+mod)%mod; if(f2>mod) f2%=mod; if(f2<0) f2 = (f2+mod)%mod; a[x++] = f2-f1; a[x++] = -f1; a[x++] = -f2; a[x++] = f1-f2; a[x++] = f1; a[x++] = f2; for(int i=0;i<x;i++) { if(a[i]<0) a[i] = (a[i]+mod)%mod; } if(n==1) printf("%I64d\n",f1); else if(n==2) printf("%I64d\n",f2); else{ int t = (n-3)%x; printf("%I64d\n",a[t]); } } return 0; }
C. Jzzhu and Chocolate
题意:
把一块n*m格的巧克力切k刀,每次只能沿着横线和竖线切,不能一格分成两部分。如果不能切k刀,输出-1.如果能,
问k刀后,最小的那块巧克力最多含有多少个格子。
算法:
1、一块n*m的巧克力最多能切n-1+m-1即n+m-2刀,如果k>n+m-2则输出-1.
2、由(n/3)*m>(n/2)*(m/2)即把一边切两刀比两边各切一刀得到的面积大,得到贪心策略:如果一边能切,
尽量先切一边再切另一边。
但是先切哪一边使得结果最优呢,两种情况分别计算取最大值就好。
P.S:突然发现,这题的程序和#32的那道神题的错误代码一模一样的思路呢,用这种思路过了那题的人们,
OMG!!!
#include<cstdio> #include<iostream> #include<cstring> using namespace std; typedef long long ll; ll n,m,k,s1,s2; int main() { while(scanf("%I64d%I64d%I64d",&n,&m,&k)!=EOF) { if(k > n+m-2) { printf("-1\n"); continue; } if(k<=m-1) s1 = n*(m/(k+1)); else s1 = n/(k-m+2); if(k<=n-1) s2 = m*(n/(k+1)); else s2 = m/(k-n+2); printf("%I64d\n",max(s1,s2)); } return 0; }
D. Jzzhu and Cities
题意:明天早上来写,今天要回去了。。。
#include<cstdio> #include<iostream> #include<cstring> #include<queue> #define maxm 300010 #define maxn 100010 #define INF 0x3f3f3f3f using namespace std; typedef long long ll; struct E { int to,next; ll w; }e[maxm<<2]; int head[maxn],cnt,n,c[maxn],mp[maxn]; bool vis[maxn]; ll dis[maxn]; priority_queue<int> q; void init() { memset(mp,0x3f,sizeof(mp)); memset(c,0,sizeof(c)); memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head)); cnt = 0; } void add(int x,int y,ll z) { e[cnt].to = y; e[cnt].w = z; e[cnt].next = head[x]; head[x] = cnt++; e[cnt].to = x; e[cnt].w = z; e[cnt].next = head[y]; head[y] = cnt++; } void spfa() { for(int i=1;i<=n;i++) dis[i] = INF; while(!q.empty()) q.pop(); dis[1] = 0; c[1] = 1; q.push(1); vis[1] = true; while(!q.empty()) { int u = q.top(); q.pop(); vis[u] = 0; for(int k = head[u];k!=-1;k=e[k].next) { int v = e[k].to; if(dis[v]>dis[u]+e[k].w) { dis[v] = dis[u]+e[k].w; c[v] = c[u]; if(!vis[v]) { q.push(v); vis[v] = true; } } else if(dis[v]==dis[u]+e[k].w) { c[v]+=c[u]; if(c[v]>2) c[v] = 2; } } } } int main() { int u,v,m,k,s,y,sum; ll w; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { init(); for(int i=0;i<m;i++) { scanf("%d%d%I64d",&u,&v,&w); add(u,v,w); } for(int i=0;i<k;i++) { scanf("%d%d",&s,&y); if(mp[s]>y) mp[s] = y; } sum = 0; for(int i=1;i<=n;i++) { if(mp[i]!=INF) { add(1,i,mp[i]); sum++; } } spfa(); for(int i=1;i<=n;i++) { if(mp[i]!=INF) { if(dis[i]<mp[i]) sum--; else if(dis[i]==mp[i] && c[i]>1) sum--; } } printf("%d\n",k-sum); } return 0; }