codeforces 187 (div2)题解
来源:互联网 发布:连接网络将服务器 编辑:程序博客网 时间:2024/04/28 23:30
http://codeforces.com/problemset/problem/315/A
这两天做了两场CF的题(div2),没事补个题解吧。
A题:题目很水,但是有些恶心的trick,比如有的罐子可以打开没有出现的编号的罐子,还有自己不能打开自己,题目没看清,WA了一堆,最后直接O(n^2)暴力水过。。。
#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>#define maxn 100010using namespace std;int a[110],b[110],num[110];int main(){ //freopen("dd.txt","r",stdin); int n,i; scanf("%d",&n); int sum=0; for(i=0;i<n;i++) { scanf("%d%d",&a[i],&b[i]); } for(i=0;i<n;i++) { for(int j=0;j<n;j++) { if(i!=j) { if(b[i]==a[j]) { num[j]=1; } } } } for(i=0;i<n;i++) sum+=num[i]; printf("%d\n",n-sum); return 0;}
http://codeforces.com/problemset/problem/315/B
#include <iostream>#include <string.h>#include <algorithm>#include <stdio.h>#define maxn 100010#define ll long longusing namespace std;ll a[maxn];int main(){ //freopen("dd.txt","r",stdin); int n,i,m; ll sum=0; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%I64d",&a[i]); while(m--) { int t,x,y; scanf("%d",&t); { if(t==1) { scanf("%d%d",&x,&y); a[x]=y-sum; } else if(t==2) { scanf("%d",&x); sum+=x; } else { scanf("%d",&x); printf("%I64d\n",sum+a[x]); } } } return 0;}
C题:题目有些长,但是看了样例还是很容易明白的,因为di的计算方法只和i前面的人还有人的总数n有关,且我们去掉人的顺序也是从小到大,所以我们可以从左往右一个一个判定a[i]是否应该被去掉,在判断的同时我们维护两个值,po表示当前待判断的人前面有多少人(没有被去掉),nn表示当前还剩多少人。那么对于每一个人计算di,若需要被去掉,则nn--,否则po++,如何快速计算di还是比较好想的,可以用类似dp的方法解决,具体实现请参考代码。
#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>#include <assert.h>#define maxn 200010#define ll long longusing namespace std;ll a[maxn];int vis[maxn];int main(){ //freopen("dd.txt","r",stdin); int n,k; scanf("%d%d",&n,&k); int i,nn=n,po=1;//nn表示还剩几人,po表示当前确定留下的人的数量 ll tmp=0,d=0; scanf("%I64d",&a[1]); for(i=2;i<=n;i++) { scanf("%I64d",&a[i]); d=tmp-po*a[i]*(nn-po-1);//计算di if(d<k)//说明去掉一个 { vis[i]=1; nn--; } else { tmp+=po*a[i]; po++; } } for(i=1;i<=n;i++) if(vis[i]) printf("%d\n",i); return 0;}
http://codeforces.com/problemset/problem/315/D
D题:首先很容易知道,若 [a, b] 串最多能obtain(具体含义见题目描述)x个 [c, d]串,则答案就为x。进一步,设[a,b]最多能obtain y个c串,则x=y/d。·求y的过程类似于求循环节,设num[i]表示[a,i]能obtain多少个c串,且设l2[i]表示[a,i]匹配完后最后一个匹配到c串的第几个字符,然后求循环节即可,具体实现还需要些细节,不嫌代码丑的话可以参考代码:
#include <iostream>#include <string.h>#include <algorithm>#include <stdio.h>#define maxn 100010using namespace std;char s1[110],s2[110];int num[10100],vis[110];int main(){ //freopen("dd.txt","r",stdin); int b,d; scanf("%d%d",&b,&d); scanf("%s%s",s1,s2); int len1=strlen(s1),len2=strlen(s2); int t=0,l1=0,l2=0,sum=0,old=0; num[0]=0; int v[26]; memset(v,0,sizeof(v)); for(int i=0;i<len1;i++) v[s1[i]-'a']++; for(int i=0;i<len2;i++) { if(!v[s2[i]-'a']) { printf("0\n"); return 0; } } memset(vis,-1,sizeof(vis)); vis[0]=0; while(1) { if(s1[l1]==s2[l2]) { l1++; l2++; } else l1++; if(l2==len2) { sum++; l2=0; } if(l1>len1) { t++; num[t]=sum; l1=0; if(vis[l2]!=-1) { old=vis[l2]; break; } vis[l2]=t; } } int tmp=0; if(b<=t) { tmp=num[b]; } else { tmp=num[t]+(num[t]-num[old])*((b-t)/(t-old)); b-=t; b%=(t-old); tmp+=num[old+b]-num[old]; } printf("%d\n",tmp/d); return 0;}
E题:很水的dp,易知我们要求的就是a串的所有不同的非下降子序列中,各位数乘积的和,我们设dp[i]表示以i结尾的非下降子序列的答案,我们从左到右一步一步更新dp值,转移方程很简单,为: dp[i]=(dp[1]+dp[2]+……dp[i])*i+i,简单点表述就是我在之前求得的以x(x<=i)结尾的非下降子序列后加上一个i,然后再加上i自身,这样可以保证序列不重复,至于为什么在纸上画画就知道了,直接这么做是不行的,显然会超时,区间和还有单点更新可以用线段树或者树状数组维护,以下是树状数组的实现。
#include <iostream>#include <stdio.h>#include <string.h>#define ll long long#define maxn 1000010#define mod 1000000007using namespace std;ll dp[maxn],c[maxn];int nn=1000000;int lowbit(int x){ return x&(-x);}void add(int x,ll val){ while(x<=nn) { c[x]=(c[x]+val)%mod; x+=lowbit(x); }}ll getsum(int x){ ll sum=0; while(x>0) { sum=(c[x]+sum)%mod; x-=lowbit(x); } return sum;}int main(){ //freopen("dd.txt","r",stdin); int i,n,x; scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&x); ll tmp=dp[x]; dp[x]=(getsum(x)*x+x)%mod; add(x,((dp[x]-tmp)%mod+mod)%mod); } ll ans=0; for(i=1;i<=1000000;i++) { ans+=dp[i]; } ans%=mod; cout<<ans<<endl; return 0;}
- codeforces 187 (div2)题解
- Codeforces 241 div2题解
- Codeforces Round330 Div2题解
- Codeforces #370(div2)题解
- codeforces #371(Div2)题解
- codeforces #373 div2题解
- codeforces round 169 div2 题解
- Codeforces Round #214div2题解
- codeforces Round #215 div2 题解
- codeforces round229 div2 前三题题解
- Codeforces Round #265(div2)题解
- codeforces round 291 div2 题解
- codeforces round 299 div2 题解
- Codeforces Round 313 div2 题解
- codeforces round 315 div2 题解
- codeforces round 319 div2 题解
- Codeforces Round #320 div2 题解
- codeforces round 321 div2 题解
- 白书的一些题目
- 庞果网---回文字符串
- Qt 编码惯例
- poj 1659
- java 最简易记事本,带详细注释,仅供参考!
- codeforces 187 (div2)题解
- cocos简单的3d渲染
- java中引用数据类型
- “第三方支付”盈利模式
- 表单隐藏域的应用
- HDOJ 1231
- 静态分布内存存储trie树
- Lombok 安装、入门 - 消除冗长的 java 代码
- 3、从零开始学习JAVA--关键字、常量、标识符、变量、运算符、转义字符、逻辑运算符、位运算符、三元运算符等