NOIp 2014
day 1 T1 生活大爆炸版石头剪刀布
标签:模拟
code(巨丑
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int main(){ 5 int n,na,nb,x,y,xa[201],xb[201],i,j,a,ans,bns; 6 cin>>n>>na>>nb; 7 for(i=1;i<=na;i++){ 8 cin>>x; 9 xa[i]=x; 10 } 11 for(j=1;j<=nb;j++){ 12 cin>>y; 13 xb[j]=y; 14 } 15 ans=0;bns=0; 16 i=0;j=0; 17 for(a=1;a<=n;a++){ 18 i++;j++; 19 if(i>na)i=1; 20 if(j>nb)j=1; 21 if(xa[i]==0&&xb[j]==1)bns++; 22 if(xa[i]==0&&xb[j]==2)ans++; 23 if(xa[i]==0&&xb[j]==3)ans++; 24 if(xa[i]==0&&xb[j]==4)bns++; 25 if(xa[i]==1&&xb[j]==0)ans++; 26 if(xa[i]==1&&xb[j]==2)bns++; 27 if(xa[i]==1&&xb[j]==3)ans++; 28 if(xa[i]==1&&xb[j]==4)bns++; 29 if(xa[i]==2&&xb[j]==0)bns++; 30 if(xa[i]==2&&xb[j]==1)ans++; 31 if(xa[i]==2&&xb[j]==3)bns++; 32 if(xa[i]==2&&xb[j]==4)ans++; 33 if(xa[i]==3&&xb[j]==0)bns++; 34 if(xa[i]==3&&xb[j]==1)bns++; 35 if(xa[i]==3&&xb[j]==2)ans++; 36 if(xa[i]==3&&xb[j]==4)ans++; 37 if(xa[i]==4&&xb[j]==0)ans++; 38 if(xa[i]==4&&xb[j]==1)ans++; 39 if(xa[i]==4&&xb[j]==2)bns++; 40 if(xa[i]==4&&xb[j]==3)bns++; 41 } 42 cout<<ans<<" "<<bns; 43 return 0; 44 }
day 1 T2 联合权值
标签:dp
转化:
step 1: 无向图,n个点,n-1条边 => 一棵树
step 2: 距离为2 => 和同一个点相连
枚举每一个点,取任意两点组合得到乘积最大值和sum
对于一个点,线性扫过所有与他相连的点,然后动态更新目前的和与目前这些点中的最大值
再到下一个点时,将下一个点的权值与这两个值相乘
code
1 #include <bits/stdc++.h> 2 using namespace std; 3 namespace gengyf{ 4 #define int long long 5 inline int read(){ 6 int x=0,f=1;char s=getchar(); 7 while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} 8 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} 9 return f*x; 10 } 11 const int mod=10007; 12 const int maxn=2e5+10; 13 struct edge{ 14 int nxt,to; 15 }e[maxn*2]; 16 int head[maxn],cnt,n,w[maxn]; 17 inline void add(int from,int to){ 18 e[++cnt].to=to;e[cnt].nxt=head[from];head[from]=cnt; 19 } 20 int ans,maxx; 21 int main(){ 22 n=read(); 23 for(int i=1;i<n;i++){ 24 int u,v; 25 u=read();v=read(); 26 add(u,v);add(v,u); 27 } 28 for(int i=1;i<=n;i++){ 29 w[i]=read(); 30 } 31 for(int i=1;i<=n;i++){ 32 int max1=0,max2=0,t1=0,t2=0; 33 for(int j=head[i];j;j=e[j].nxt){ 34 if(w[e[j].to]>max1){ 35 max2=max1;max1=w[e[j].to]; 36 } 37 else if(w[e[j].to]>max2)max2=w[e[j].to]; 38 t1=(t1+w[e[j].to])%mod; 39 t2=(t2+w[e[j].to]*w[e[j].to])%mod; 40 } 41 t1=t1*t1%mod; 42 ans=(ans+t1-t2+mod)%mod; 43 if(maxx<max1*max2)maxx=max1*max2; 44 } 45 printf("%lld %lld",maxx,ans); 46 return 0; 47 } 48 } 49 signed main(){ 50 gengyf::main(); 51 return 0; 52 }
day 1 T3 飞扬的小鸟
标签:dp
上升 -> 完全背包 单位时间上升是可以叠加的
下降 -> 01背包 单位时间只能下降1次
转移:
<1>上升
<2>飞到顶上
<3>下降
<4>有柱子
上升:$f[i][j]=min(f[i][j],min(f[i-1][j-lift[i-1],f[i][j-lift[i-1]])+1)$
code
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define MAXN 1<<30 4 struct Pipe{ 5 int pos,up,bottom; 6 }pipe[10010]; 7 int n,m,k,lift[10010],down[10010],f[10010][1010]; 8 bool cmp(Pipe a,Pipe b){ 9 return a.pos<b.pos; 10 } 11 int main(){ 12 scanf("%d%d%d",&n,&m,&k); 13 for(int i=0;i<=n-1;i++){ 14 scanf("%d%d",&lift[i],&down[i]); 15 } 16 for(int i=1;i<=k;i++){ 17 scanf("%d%d%d",&pipe[i].pos,&pipe[i].bottom,&pipe[i].up); 18 } 19 sort(pipe+1,pipe+k+1,cmp); 20 for(int i=0;i<=n;i++) 21 for(int j=0;j<=m;j++){ 22 f[i][j]=MAXN; 23 } 24 for(int i=1;i<=m;i++)f[0][i]=0; 25 int nump=1; 26 for(int i=1;i<=n;i++){ 27 int lower=1,upper=m; 28 if(pipe[nump].pos==i){ 29 upper=pipe[nump].up-1; 30 lower=pipe[nump++].bottom+1; 31 } 32 for(int j=1;j<=upper;j++){ 33 for(int k=j-lift[i-1];k<=m;k++){ 34 if(k>j-lift[i-1]&&j<m)break; 35 if(k>=1)f[i][j]=min(f[i][j],min(f[i-1][k],f[i][k])+1); 36 } 37 } 38 for(int j=lower;j<=upper;j++){ 39 if(j+down[i-1]<=m){ 40 f[i][j]=min(f[i][j],f[i-1][j+down[i-1]]); 41 } 42 } 43 for(int j=1;j<=lower-1;j++)f[i][j]=MAXN; 44 } 45 int minn=MAXN; 46 bool flag=false; 47 for(int i=n;i>=1;i--){ 48 for(int j=1;j<=m;j++){ 49 if(f[i][j]!=MAXN){ 50 flag=true; 51 minn=min(minn,f[i][j]); 52 } 53 } 54 if(flag){ 55 if(i==n){ 56 printf("1 %d",minn); 57 return 0; 58 } 59 else{ 60 for(int j=k;j>=1;j--){ 61 if(i>=pipe[j].pos){ 62 printf("0 %d",j); 63 return 0; 64 } 65 } 66 } 67 } 68 } 69 printf("0 0"); 70 return 0; 71 }
day 2 T1 无线网络发射器选址
标签:模拟,二维前缀和
枚举每一个点,更新最大值+统计答案个数
code
1 #include <bits/stdc++.h> 2 using namespace std; 3 namespace gengyf{ 4 #define ll long long 5 inline int read(){ 6 int x=0,f=1;char s=getchar(); 7 while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} 8 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} 9 return f*x; 10 } 11 int a[130][130],n,d,s[130][130],ans,cnt; 12 int main(){ 13 d=read();n=read(); 14 for(int i=1;i<=n;i++){ 15 int x,y,num; 16 x=read();y=read();num=read(); 17 a[x][y]=num; 18 } 19 for(int i=0;i<=128;i++) 20 for(int j=0;j<=128;j++){ 21 s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]; 22 } 23 for(int i=0;i<=128;i++) 24 for(int j=0;j<=128;j++){ 25 int x1,x2,y1,y2; 26 x1=max(i-d,0);y1=max(j-d,0); 27 x2=min(i+d,128);y2=min(j+d,128); 28 int tmp=s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]; 29 if(tmp==ans)cnt++; 30 else if(tmp>ans){ 31 cnt=1;ans=tmp; 32 } 33 } 34 printf("%d %d",cnt,ans); 35 return 0; 36 } 37 } 38 signed main(){ 39 gengyf::main(); 40 return 0; 41 }
day 2 T2 寻找道路
标签:图论,最短路
对于要求1可以反向建图dfs标记能到终点的点
如果标记的点,如果它的出边有未被标记的,则不合法,取消标记
对于要求2在标记的点中跑最短路
code
1 #include <bits/stdc++.h> 2 using namespace std; 3 namespace gengyf{ 4 #define ll long long 5 inline int read(){ 6 int x=0,f=1;char s=getchar(); 7 while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} 8 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} 9 return f*x; 10 } 11 const int maxn=1e4+10; 12 vector<int>G[maxn]; 13 queue<int>q; 14 bool v[maxn],vis[maxn]; 15 int n,m,ans[maxn],s,t; 16 int main(){ 17 n=read();m=read(); 18 for(int i=1;i<=m;i++){ 19 int a,b;a=read();b=read(); 20 if(a==b)continue; 21 G[b].push_back(a); 22 } 23 s=read();t=read(); 24 v[t]=1;q.push(t); 25 while(!q.empty()){ 26 int x=q.front(); 27 q.pop(); 28 for(int i=0;i<G[x].size();i++){ 29 if(!v[G[x][i]]){ 30 v[G[x][i]]=1; 31 q.push(G[x][i]); 32 } 33 } 34 } 35 memcpy(vis,v,sizeof(v)); 36 for(int i=1;i<=n;i++){ 37 if(!v[i]){ 38 for(int j=0;j<G[i].size();j++){ 39 if(vis[G[i][j]])vis[G[i][j]]=0; 40 } 41 } 42 } 43 q.push(t); 44 while(!q.empty()){ 45 int x=q.front(); 46 q.pop(); 47 for(int i=0;i<G[x].size();i++){ 48 if(vis[G[x][i]]){ 49 q.push(G[x][i]); 50 vis[G[x][i]]=0; 51 ans[G[x][i]]=ans[x]+1; 52 } 53 } 54 } 55 if(ans[s]==0)puts("-1"); 56 else printf("%d",ans[s]); 57 return 0; 58 } 59 } 60 signed main(){ 61 gengyf::main(); 62 return 0; 63 }
day 2 T3 解方程
标签:数学
秦九韶算法 O(n)
枚举[1,m]代入函数f(x)看是否为0,注意取模
code
1 #include <bits/stdc++.h> 2 using namespace std; 3 namespace gengyf{ 4 #define ll long long 5 const int p=1e9+7; 6 const int maxn=1e6+10; 7 inline ll read(){ 8 ll x=0,f=1; 9 char c=getchar(); 10 while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} 11 while(c>='0'&&c<='9'){x=((x*10)+c-'0')%p;c=getchar();} 12 return x*f; 13 } 14 ll sum,a[110],n,m,ans[maxn],cnt; 15 bool t=1; 16 bool calc(ll x){ 17 sum=0; 18 for(ll i=n;i>=1;i--){ 19 sum=((a[i]+sum)*x)%p; 20 } 21 sum=(sum+a[0])%p; 22 return !sum; 23 } 24 int main(){ 25 n=read(); 26 m=read(); 27 for(ll i=0;i<=n;i++){ 28 a[i]=read(); 29 } 30 for(ll i=1;i<=m;i++){ 31 if(calc(i)){ 32 t=false; 33 cnt++; 34 ans[cnt]=i; 35 } 36 } 37 if(t){ 38 cout<<cnt<<endl; 39 return 0; 40 } 41 printf("%lld ",cnt); 42 for(int i=1;i<=cnt;i++){ 43 printf("%lld ",ans[i]); 44 } 45 return 0; 46 } 47 } 48 signed main(){ 49 gengyf::main(); 50 return 0; 51 }
4102年的题真友好