codeforces 283,284(Round #174)题解
来源:互联网 发布:linux下好用的输入法 编辑:程序博客网 时间:2024/04/27 23:30
2A:暴力即可,有数学方法,答案即为phi(phi(p)),具体证明详见
http://jijiwaiwai163.blog.163.com/blog/static/186296211201261133849397/
2B:记录'I'的个数a,'A'的个数b,a=0显然答案就是b,a=1答案显然只能为1,a>=2答案显然为0。
2C(1A):由于1~i均加一个值,完全没必要1~i都记录,只需记录每次加的最后一个数加了多少即可,每次弹出的时候,把最后一个数累加的加到前面一个数即可,注意,弹出时一定要清零,否则以后再加的时候就错了(thx谷神T_T)
上代码:
#include<cstdio> #include<algorithm>#include<iostream>#include<cstring>#include<cmath>using namespace std;const int N=200005;int a[N],w[N];int main(){ int i,t,n; scanf("%d",&n); double sum=0; int l=1; int x,y; for(i=0;i<n;++i) { scanf("%d",&t); if(t==1) { scanf("%d%d",&x,&y); a[x]=a[x]+y; sum+=(double)x*y; } if(t==2) { scanf("%d",&x); sum+=(double)x; w[++l]=x; } if(t==3) { sum-=(double)(w[l]+a[l]); a[l-1]+=a[l]; w[l]=a[l]=0; l--; } printf("%.6lf\n",sum/(double)l); } return 0;}
2D(1B):首先看数据范围,显然不能暴力。然后又会想到每个数列主要区别在于a1加的值,其他区别在于第二步从第几个数计算。所以我们只需记忆化搜索出从a[2],到a[n]开始计算出的每个y的值,再分别加上i即可。
#include<cstdio>#include<iostream>#include<algorithm>using namespace std;const int N=200005;int n;long long a[N],y[N][2];bool v[N][2];long long dfs(int x,int t){ if(x<=0 || x>n) return 0; if(x==1) return -1; if(v[x][t]) return y[x][t]; v[x][t]=true; y[x][t]=-1; if(t==1) y[x][t]=dfs(x-a[x],0); if(t==0) y[x][t]=dfs(x+a[x],1); if(y[x][t]!=-1) y[x][t]+=a[x]; return y[x][t];}int main(){ int i; scanf("%d",&n); for(i=2;i<=n;++i) scanf("%I64d",&a[i]); for(i=2;i<=n;++i) if(!v[i][1]) dfs(i,1);//记忆化搜素,搜索a[2]到a[n]状态开始计算出的值 for(i=1;i<n;++i) if(y[i+1][1]==-1) printf("-1\n"); else printf("%I64d\n",y[i+1][1]+i); return 0;}2E(1C):完全背包,比较水,关键在于有物品数量是严格大于其他物品的,这种情况只需把前者价值加上后者即可。
注意这种物品有两种,一种是只限制别人,不被限制,另一种是限制别人同时自己也被限制。搞个ind[]数组存储,
先存第一类,再存第二类,这样第一类价值可以累加到第二类上,第二类价值可以加到只被限制的物品上,完全背包即可
#include<iostream>#include<algorithm>#include<cstring>#include<cstdio>using namespace std;const int N=305,MOD=1000000007;int w[N],p[N],vis[N],dep[N],ind[N],f[100005];int main(){ int i,j,n,q,t; int x,y; scanf("%d%d%d",&n,&q,&t); for(i=1;i<=n;++i) scanf("%d",&w[i]); for(i=1;i<=q;++i) { scanf("%d%d",&x,&y); p[x]=y; vis[x]=1; dep[y]++; } int tot=0; for(i=1;i<=n;++i) if(vis[i] && !dep[i]) ind[++tot]=i; for(i=1;i<=tot;i++) {int now=ind[i];if(vis[p[now]] && dep[p[now]]==1) ind[++tot] = p[now]; } if(tot!=q) printf("0"); else { for(i=1;i<=tot;++i) { int now=ind[i]; int af=p[now]; w[af]+=w[now]; t=t-w[now]; if(t<0) {printf("0");return 0;} } f[0]=1; for(i=1;i<=n;++i) { for(j=w[i];j<=t;++j) { f[j]=(f[j]+f[j-w[i]])%MOD; } } printf("%d",f[t]); } return 0;}
1D:不错的题,f[n]表示满足条件的数有多少,ans=min(n-f[n])。对于j<i如果a[i]为奇数且a[j]%a[i]=0,显然满足;
如果a[i]为偶数,a[j]%a[i]=a[i]/2,也满足(想一想,为什么)。如果a[i]为偶数a[i-2],a[i-1],a[i]若都想成立,
a[i-1]需为a[i]/2(我自己YY感觉的T_T,大致推了一下)。
#include<cstdio>//dp,记录满足条件最多多少个数即可 #include<iostream>#include<algorithm>using namespace std;const int N=5005;long long a[N],f[N];int main(){ int i,j,n; scanf("%d",&n); for(i=1;i<=n;++i) scanf("%I64d",&a[i]); for(i=1;i<=n;++i) { long long x=a[i]; f[i]=1; for(j=i-1;j>=1;--j) { if((x&1 && a[j]%x==0)|| (!(x&1) && a[j]%x==x/2)) f[i]=max(f[i],f[j]+1); if(!(x&1)) x=x>>1; } } long long ans=1000000; for(i=1;i<=n;++i) ans=min(ans,n-f[i]); printf("%I64d",ans); return 0;}
- codeforces 283,284(Round #174)题解
- 【codeforces】Codeforces Round #284 (Div. 1) 【题解】
- 【codeforces】Codeforces Round #283 (Div. 2) 【题解】
- codeforces Round #180题解
- Codeforces Round #334 题解
- Codeforces Round #366 题解
- Codeforces Round #397 题解
- Codeforces Round #424 题解
- Codeforces Round #433 题解
- Codeforces Round #434 题解
- Codeforces Round #438 题解
- Codeforces Round #438 题解
- Codeforces Round #432 题解
- codeforces 282(Round #173)题解
- codeforces 1(Round #1)题解
- codeforces 285(Round #175)题解
- codeforces 286(Round #176)题解
- codeforces round 169 div2 题解
- Sum Root to Leaf Numbers
- 操作系统第二章作业
- ASP.NET 中 AdRotator(广告控件)的使用
- C++第4周项目2 - 三角形类2
- uva10282 - Babelfish(字典)
- codeforces 283,284(Round #174)题解
- QT 学习笔记 (一) 环境安装
- 做了个超级简单的mysql数据库demo
- C++第4周项目3 - 多文件组织程序
- 仿Iphone从屏幕底部弹出半透明的PopupWindow
- makefile 指定库的路径
- C# 委托(delegate) 的小应用
- Java之冒泡排序
- update algirothm