Codeforces gym 2014 Nordic Collegiate Programming Contest(最初版,有过题再更新)
来源:互联网 发布:网络语言爸爸什么意思 编辑:程序博客网 时间:2024/04/26 04:15
2014.10.25 训练,和一个队友做cf上的gym的比赛,过了6题。
感觉还可以,有几道水题没有卡住,一道模拟,一道贪心,一道高精度+推公式
剩下的,一道kmp(非裸题),一道dfs搜索,一道数学期望
还有一道G题看了没做,问了学长,是一个环连着多个树,然后dp.. 没弄出来。感觉这个姿势很神奇
G I J 已经被我亮星了,改天过了,再更新本博文
已过题目:ACDEFHK
待过题目:GIJ
感觉过不了的题目(=。=!):BF
这题还是很简单的。
每个点要不然有登机口,要不然没有。
对于一个联通图,如果一个点确定了是否有登机口,那么这个联通图中的所有点都可以确定是否有登机口。
对于每个联通图,dfs搜索,假设起点有和没有两种情况来搜。
要分情况讨论,注意impossible成立的条件。
这里细讲太过于冗杂,就不陈述了。代码如下:
(dfs不太好写)
//Hello. I'm Peter.#include<cstdio>#include<iostream>#include<sstream>#include<cstring>#include<string>#include<cmath>#include<cstdlib>#include<algorithm>#include<functional>#include<cctype>#include<ctime>#include<stack>#include<queue>#include<vector>#include<set>#include<map>using namespace std;typedef long long ll;typedef long double ld;#define peter cout<<"i am peter"<<endl#define input freopen("data.txt","r",stdin)#define randin srand((unsigned int)time(NULL))#define INT (0x3f3f3f3f)*2#define LL (0x3f3f3f3f3f3f3f3f)*2#define gsize(a) (int)a.size()#define len(a) (int)strlen(a)#define slen(s) (int)s.length()#define pb(a) push_back(a)#define clr(a) memset(a,0,sizeof(a))#define clr_minus1(a) memset(a,-1,sizeof(a))#define clr_INT(a) memset(a,INT,sizeof(a))#define clr_true(a) memset(a,true,sizeof(a))#define clr_false(a) memset(a,false,sizeof(a))#define clr_queue(q) while(!q.empty()) q.pop()#define clr_stack(s) while(!s.empty()) s.pop()#define rep(i, a, b) for (int i = a; i < b; i++)#define dep(i, a, b) for (int i = a; i > b; i--)#define repin(i, a, b) for (int i = a; i <= b; i++)#define depin(i, a, b) for (int i = a; i >= b; i--)#define pi acos(-1.0)#define eps 1e-6#define MOD 1000000007#define MAXN 200100#define N#define Mint n,m,a,b,c;struct Edge{ int from,to,next; int val;}edge[2*MAXN];int head[MAXN],w;void add_edge(int from,int to,int val){ w++; edge[w].from=from; edge[w].to=to; edge[w].val=val; edge[w].next=head[from]; head[from]=w;}bool vis1[MAXN],vis2[MAXN],must[MAXN];void dfs(int now,bool *vis,int &anst){ vis[now]=true; if(must[now]) anst+=1; int i,to,val; for(i=head[now];i!=-1;i=edge[i].next){ to=edge[i].to; val=edge[i].val; if(vis[to]){ if(must[now]&&val==0){ anst=-1; return; } else if(must[now]&&val==1&&must[to]){ anst=-1; return; } else if(must[now]&&val==2&&!must[to]){ anst=-1; return; } else if(!must[now]&&val==0&&must[to]){ anst=-1; return; } else if(!must[now]&&val==1&&!must[to]){ anst=-1; return; } else if(!must[now]&&val==2){ anst=-1; return; } } else{//vis[to]=false; if(must[now]&&val==0){ anst=-1; return; } else if(must[now]&&val==1){ must[to]=false; dfs(to,vis,anst); } else if(must[now]&&val==2){ must[to]=true; dfs(to,vis,anst); } else if(!must[now]&&val==0){ must[to]=false; dfs(to,vis,anst); } else if(!must[now]&&val==1){ must[to]=true; dfs(to,vis,anst); } else if(!must[now]&&val==2){ anst=-1; return; } if(anst==-1) return; } }}int main(){ cin>>n>>m; repin(i,1,n){ head[i]=-1; vis1[i]=false; vis2[i]=false; } w=0; repin(i,1,m){ scanf("%d %d %d",&a,&b,&c); add_edge(a,b,c); add_edge(b,a,c); } int ans=0,anst1,anst2; repin(i,1,n){ if(vis1[i] || vis2[i]) continue; must[i]=true; anst1=0; dfs(i,vis1,anst1); must[i]=false; anst2=0; dfs(i,vis2,anst2); if(anst1==-1&&anst2==-1){ printf("impossible\n"); exit(0); } else if(anst1!=-1&&anst2==-1){ ans+=anst1; } else if(anst1==-1&&anst2!=-1){ ans+=anst2; } else ans+=min(anst1,anst2); } printf("%d\n",ans);}
这题也不单单是高精度问题,需要将公式推出来
不难发现,Sn=C(n+1),然后求C(n)题目已经给了个公式C(n)=(2n,n)/(n+1);
(2n,n)就是排列组合中的组合问题,即2n个里选n个的总数,那么求(2n,n)复杂度就是O(n)的了
接下来就是用高精度来做,模拟下就出来了。
一开始我的思路是把每一个C(n)求出来,再求S(n),用java做T了
下面java7过的代码,c++高精度模版我还没有,以后要搞一个自己的
import java.io.*;import java.util.*;import java.math.BigInteger;public class Main { public static void main(String[] args) throws Exception { Scanner cin=new Scanner(System.in); int n=cin.nextInt(); BigInteger up,down; up=down=new BigInteger("1"); BigInteger tt=new BigInteger((2*n+2)+""); BigInteger one=new BigInteger("1"); for(int i=1;i<=n+1;i++){ BigInteger t=new BigInteger(i+""); down=down.multiply(t); up=up.multiply(tt); tt=tt.subtract(one); } BigInteger ans=up.divide(down); BigInteger t1=new BigInteger((n+2)+""); ans=ans.divide(t1); System.out.println(ans); }}
这题就是求期望分数
期望分数=所有的 (分数*该分数占的概率)
原谅我偷懒不写出数学公式来了0.0
最后判断浮点相等别忘了eps
代码如下:
//Hello. I'm Peter.#include<cstdio>#include<iostream>#include<sstream>#include<cstring>#include<string>#include<cmath>#include<cstdlib>#include<algorithm>#include<functional>#include<cctype>#include<ctime>#include<stack>#include<queue>#include<vector>#include<set>#include<map>using namespace std;typedef long long ll;typedef long double ld;#define peter cout<<"i am peter"<<endl#define input freopen("data.txt","r",stdin)#define randin srand((unsigned int)time(NULL))#define INT (0x3f3f3f3f)*2#define LL (0x3f3f3f3f3f3f3f3f)*2#define gsize(a) (int)a.size()#define len(a) (int)strlen(a)#define slen(s) (int)s.length()#define pb(a) push_back(a)#define clr(a) memset(a,0,sizeof(a))#define clr_minus1(a) memset(a,-1,sizeof(a))#define clr_INT(a) memset(a,INT,sizeof(a))#define clr_true(a) memset(a,true,sizeof(a))#define clr_false(a) memset(a,false,sizeof(a))#define clr_queue(q) while(!q.empty()) q.pop()#define clr_stack(s) while(!s.empty()) s.pop()#define rep(i, a, b) for (int i = a; i < b; i++)#define dep(i, a, b) for (int i = a; i > b; i--)#define repin(i, a, b) for (int i = a; i <= b; i++)#define depin(i, a, b) for (int i = a; i >= b; i--)#define pi acos(-1.0)#define eps 1e-6#define MOD 1000000007#define MAXN 100100#define N#define M 1000int a1,b1,a2,b2,n1,n2;int number1[M],number2[M];double avepoint1,avepoint2;int dcmp(double x){ if(fabs(x)<eps) return 0; else if(x<0) return -1; else return 1;}int main(){ cin>>a1>>b1>>a2>>b2; repin(i,a1,b1){ repin(j,a2,b2){ number1[i+j]+=1; } } n1=(b1-a1+1)*(b2-a2+1); avepoint1=0.0; repin(i,a1+a2,b1+b2){ double t=(double)1.0*number1[i]/n1; avepoint1+=t*i; } cin>>a1>>b1>>a2>>b2; repin(i,a1,b1){ repin(j,a2,b2){ number2[i+j]+=1; } } n2=(b1-a1+1)*(b2-a2+1); avepoint2=0.0; repin(i,a1+a2,b1+b2){ double t=(double)1.0*number2[i]/n2; avepoint2+=t*i; } int t=dcmp(avepoint1-avepoint2); if(t==0) printf("Tie\n"); else if(t<0) printf("Emma\n"); else printf("Gunnar\n");}
这题是贪心问题。
我不知道为什么是对的,和队友讨论了后,得出了个结论,但没有严格证明,没有图也不好说,就不陈述了。
将数列从小到大排序,从后往前扫,假设这个点左边全部用横向消除方法,右边全部用纵向消除方法
每次左边和右边的方法都可以知道需要多少步,维护最小值即可
代码如下:
//Hello. I'm Peter.#include<cstdio>#include<iostream>#include<sstream>#include<cstring>#include<string>#include<cmath>#include<cstdlib>#include<algorithm>#include<functional>#include<cctype>#include<ctime>#include<stack>#include<queue>#include<vector>#include<set>#include<map>using namespace std;typedef long long ll;typedef long double ld;#define peter cout<<"i am peter"<<endl#define input freopen("data.txt","r",stdin)#define randin srand((unsigned int)time(NULL))#define INT (0x3f3f3f3f)*2#define LL (0x3f3f3f3f3f3f3f3f)*2#define gsize(a) (int)a.size()#define len(a) (int)strlen(a)#define slen(s) (int)s.length()#define pb(a) push_back(a)#define clr(a) memset(a,0,sizeof(a))#define clr_minus1(a) memset(a,-1,sizeof(a))#define clr_INT(a) memset(a,INT,sizeof(a))#define clr_true(a) memset(a,true,sizeof(a))#define clr_false(a) memset(a,false,sizeof(a))#define clr_queue(q) while(!q.empty()) q.pop()#define clr_stack(s) while(!s.empty()) s.pop()#define rep(i, a, b) for (int i = a; i < b; i++)#define dep(i, a, b) for (int i = a; i > b; i--)#define repin(i, a, b) for (int i = a; i <= b; i++)#define depin(i, a, b) for (int i = a; i >= b; i--)#define pi acos(-1.0)#define eps 1e-6#define MOD 1000000007#define MAXN 100100#define N#define M 1000int n,ans;int h[MAXN];int main(){ cin>>n; repin(i,1,n){ scanf("%d",h+i); } sort(h+1,h+1+n); ans=n; depin(i,n,1){ int t=h[i]+(n-i); ans=min(ans,t); } cout<<ans<<endl;}
给两个时钟,每个时钟有n个指针,方向散乱无序,告诉你12点钟方向顺时针转到该指针的角度是多少
问,将第一个时钟旋转某个角度,是否可以和第二个时钟完全重合?
只需要输出是否即可,不需要知道旋转多少度
思路如下
将2个时钟指针角度都从小到大排序
每个时钟求出下一个指针和上一个指针的角度差,构成2个数组(注意这个过程末尾和第一个指针构成的角度)
现在需要做的是,判断下一个数组头尾移动后,能否和第一个数组重合。
将第一个数组复制一遍,从n长度,变成2n,d1[i+n]==d[i]
那么,问题就变成了,下面这个长度为n的数组,是否是上面那个长度为2n数组的子串
跑一发kmp就出来了
代码如下:
//Hello. I'm Peter.#include<cstdio>#include<iostream>#include<sstream>#include<cstring>#include<string>#include<cmath>#include<cstdlib>#include<algorithm>#include<functional>#include<cctype>#include<ctime>#include<stack>#include<queue>#include<vector>#include<set>#include<map>using namespace std;typedef long long ll;typedef long double ld;#define peter cout<<"i am peter"<<endl#define input freopen("data.txt","r",stdin)#define randin srand((unsigned int)time(NULL))#define INT (0x3f3f3f3f)*2#define LL (0x3f3f3f3f3f3f3f3f)*2#define gsize(a) (int)a.size()#define len(a) (int)strlen(a)#define slen(s) (int)s.length()#define pb(a) push_back(a)#define clr(a) memset(a,0,sizeof(a))#define clr_minus1(a) memset(a,-1,sizeof(a))#define clr_INT(a) memset(a,INT,sizeof(a))#define clr_true(a) memset(a,true,sizeof(a))#define clr_false(a) memset(a,false,sizeof(a))#define clr_queue(q) while(!q.empty()) q.pop()#define clr_stack(s) while(!s.empty()) s.pop()#define rep(i, a, b) for (int i = a; i < b; i++)#define dep(i, a, b) for (int i = a; i > b; i--)#define repin(i, a, b) for (int i = a; i <= b; i++)#define depin(i, a, b) for (int i = a; i >= b; i--)#define pi acos(-1.0)#define eps 1e-6#define MOD 1000000007#define MAXN 200100#define N#define Mint n;int a[MAXN],b[MAXN];int d1[2*MAXN],d2[MAXN];int nextpos[MAXN];void Build_nextpos(){ int i,j; i=0; nextpos[0]=j=-1; while(i<n){ if(j==-1 || d2[i]==d2[j]){ nextpos[i+1]=j+1; if(d2[j+1]==d2[i+1]) nextpos[i+1]=nextpos[j+1]; i++; j=j+1; } else j=nextpos[j]; }}bool kmp(){ int i,j; i=j=0; while(i<2*n && j<n){ if(j==-1 || d1[i]==d2[j]){ i++; j++; } else j=nextpos[j]; } if(j==n) return true; else return false;}int main(){ cin>>n; rep(i,0,n){ scanf("%d",a+i); } sort(a,a+n); rep(i,0,n){ scanf("%d",b+i); } sort(b,b+n); rep(i,0,n){ if(i==n-1) d1[i]=360000-a[i]+a[0]; else d1[i]=a[i+1]-a[i]; } rep(i,n,2*n){ d1[i]=d1[i-n]; } rep(i,0,n){ if(i==n-1) d2[i]=360000-b[i]+b[0]; else d2[i]=b[i+1]-b[i]; } Build_nextpos(); if(kmp()) printf("possible\n"); else printf("impossible\n");}
简单模拟题
判断火车人数是否小于0
判断火车人数是否超过限制
判断火车是否存在人没满但却有人等待的情况
判断最终火车是否为空
代码如下:
//Hello. I'm Peter.#include<cstdio>#include<iostream>#include<sstream>#include<cstring>#include<string>#include<cmath>#include<cstdlib>#include<algorithm>#include<functional>#include<cctype>#include<ctime>#include<stack>#include<queue>#include<vector>#include<set>#include<map>using namespace std;typedef long long ll;typedef long double ld;#define peter cout<<"i am peter"<<endl#define input freopen("data.txt","r",stdin)#define randin srand((unsigned int)time(NULL))#define INT (0x3f3f3f3f)*2#define LL (0x3f3f3f3f3f3f3f3f)*2#define gsize(a) (int)a.size()#define len(a) (int)strlen(a)#define slen(s) (int)s.length()#define pb(a) push_back(a)#define clr(a) memset(a,0,sizeof(a))#define clr_minus1(a) memset(a,-1,sizeof(a))#define clr_INT(a) memset(a,INT,sizeof(a))#define clr_true(a) memset(a,true,sizeof(a))#define clr_false(a) memset(a,false,sizeof(a))#define clr_queue(q) while(!q.empty()) q.pop()#define clr_stack(s) while(!s.empty()) s.pop()#define rep(i, a, b) for (int i = a; i < b; i++)#define dep(i, a, b) for (int i = a; i > b; i--)#define repin(i, a, b) for (int i = a; i <= b; i++)#define depin(i, a, b) for (int i = a; i >= b; i--)#define pi acos(-1.0)#define eps 1e-6#define MOD 1000000007#define MAXN 100100#define N#define M 1000int c,n,nowcapacity;void impossible(){ printf("impossible\n"); exit(0);}int main(){ cin>>c>>n; nowcapacity=0; int out,in,wait; repin(i,1,n){ scanf("%d %d %d",&out,&in,&wait); nowcapacity-=out; if(nowcapacity<0) impossible(); nowcapacity+=in; if(nowcapacity>c) impossible(); if(nowcapacity!=c && wait!=0) impossible(); } if(nowcapacity!=0) impossible(); printf("possible\n");}
- Codeforces gym 2014 Nordic Collegiate Programming Contest(最初版,有过题再更新)
- CF 2014 Nordic Collegiate Programming Contest E Opening Ceremony
- CF 2014 Nordic Collegiate Programming Contest H.Clock Pictures
- 2014 Nordic Collegiate Programming Contest A - Amanda Lounges
- Nordic Collegiate Programming Contest 2016题解
- Nordic Collegiate Programming Contest 2017 题解
- Codeforces Gym 2015 ACM Amman Collegiate Programming Contest
- Codeforces Gym 2015 ACM Arabella Collegiate Programming Contest
- 2017-2018 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2017) 部分题/平衡树/最小环/思路bfs
- 【Codeforces】2015-2016 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2015) E 线段树+离散化
- 【Codeforces】2015-2016 ACM-ICPC Nordic Collegiate Programming Contest (NCPC 2015) A Adjoin the Netwo
- GYM 2015 ACM Syrian Collegiate Programming Contest
- GYM 2017 ACM Amman Collegiate Programming Contest
- The 2011 Nordic Collegiate Programming Contest October 01, 2011
- CSU 1886: Phone List(2007 Nordic Collegiate Programming Contest)
- CSU 1892: Nested Dolls(2007 Nordic Collegiate Programming Contest)
- Codeforces Gym 2015 ACM Arabella Collegiate Programming Contest(二月十日训练赛)
- CodeFroces GYM 2016-2017 ACM-ICPC, Egyptian Collegiate Programming Contest (ECPC 16) B.street(最短路)
- PAT (Advanced Level) Practise 1016. Phone Bills (25)
- Centos系统备份与恢复教程
- win7下硬盘安装Ubuntu 14.04
- N!(杭电1042)(数组实现+java实现)
- IOS开发NSBundle对象使用详解
- Codeforces gym 2014 Nordic Collegiate Programming Contest(最初版,有过题再更新)
- storm的学习与使用(三)
- hdu2391(简单dp)
- LeetCode 76 Minimum Window Substring
- 二、ROS相关网站汇总
- word2010文档中的网址链接显示的是乱码
- win8.1+vs2012环境下装boost1.55
- NSSortDescriptor(数组排序)
- SAPI 包含sphelper.h编译错误解决方案