考完发现写了两个文件输入。
爆零了。
1264. 乱头发节(badhair.pas/c/cpp)
(File IO): input:badhair.in output:badhair.out
Time Limits: 1000 ms Memory Limits: 65536 KB Detailed Limits
Goto ProblemSet用了双向链表(初赛整蒙的玩意)。
求出右边第一个比它大的值,再拿相对位置处理一下即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 ll read(){ 5 ll x=0,f=1; 6 char c=getchar(); 7 while(!isdigit(c)){ 8 if(c=='-') f=-1; 9 c=getchar(); 10 } 11 while(isdigit(c)){ 12 x=(x<<1)+(x<<3)+(c^48); 13 c=getchar(); 14 } 15 return x*f; 16 } 17 const int N=80010; 18 struct node{ 19 ll pos,h; 20 bool operator < (const node &x)const{ 21 if(h==x.h)return pos<x.pos; 22 return h<x.h; 23 } 24 }cow[N]; 25 ll pre[N],nxt[N]; 26 ll high[N]; 27 ll cnt,n; 28 ll ans; 29 int main(){ 30 // freopen("badhair.in","r",stdin); 31 // freopen("badhair.out","w",stdout); 32 n=read(); 33 for(int i=1;i<=n;i++){ 34 cow[i].h=read(); 35 cow[i].pos=i; 36 } 37 for(int i=1;i<=n;i++){ 38 pre[i]=i-1; 39 nxt[i]=i+1; 40 } 41 sort(cow+1,cow+n+1); 42 for(int i=1;i<=n;i++){ 43 nxt[pre[cow[i].pos]]=nxt[cow[i].pos]; 44 pre[nxt[cow[i].pos]]=pre[cow[i].pos]; 45 } 46 ll ans=0; 47 for(int i=1;i<=n;i++) 48 ans+=nxt[i]-i-1; 49 printf("%lld",ans); 50 return 0; 51 }
1265. Round Numbers(rndnum.pas/c/cpp)
(File IO): input:rndnum.in output:rndnum.out
Time Limits: 1000 ms Memory Limits: 65536 KB Detailed Limits
Goto ProblemSet这题是数位dp,思路慢慢讲。
考虑一个数100100:
我们知道100000~1是很好求得答案的:
1.考虑第2位放1,那么3~6位可以随便放,即1????
注意到0的数量大于等于1的数量,因此,这部分答案就是:
len为数字二进制位数。
1 for(int i=len-1;i>=1;i--){ 2 for(int j=i/2-1;j>=1;j--){ 3 ans+=f[i-1][j]; 4 } 5 }
2.加上形如1000……的答案,结果加上len-1;
3.对于100100~100000的答案,我们从后往前考虑:
对于第一个遇到的1(第4位),我们看100100能不能计入答案,如果能就计入,否则无论怎么缩小都是没有意义的,可以直接往前面的1看去。
这里可以,因此我们计入一个100100,再删去这个位置上的1,考虑后面两位可以怎么放。
显然,能放的1的个数可以计算得出(可以维护一个前缀和),再套用组合数即可。
处理完这个就可以往前走了。(建议手推)
1 for(int i=1;i<=len;i++){ 2 if(s[i]==0) continue; 3 if(i==len) break; 4 if(len-sum[i]>=sum[i]) ans++; 5 else continue; 6 sum[i]--; 7 int mon=i-1; 8 int son=min(mon,len/2-sum[i]); 9 for(int j=son;j>=1;j--){ 10 ans+=f[mon][j]; 11 } 12 }
最后给出全部代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int read(){ 4 int x=0,f=1; 5 char c=getchar(); 6 while(!isdigit(c)){ 7 if(c=='-') f=-1; 8 c=getchar(); 9 } 10 while(isdigit(c)){ 11 x=(x<<1)+(x<<3)+(c^48); 12 c=getchar(); 13 } 14 return x*f; 15 } 16 int st,nd; 17 int f[100][100]; 18 int solve(int num){ 19 if(!num) return 0; 20 int ans=0; 21 int s[200],sum[200]; 22 memset(s,0,sizeof(s)); 23 memset(sum,0,sizeof(sum)); 24 int len=0; 25 while(num){ 26 len++; 27 if(num&1) s[len]=1; 28 num>>=1; 29 } 30 for(int i=len;i>=1;i--){ 31 sum[i]=sum[i+1]+s[i]; 32 } 33 for(int i=1;i<=len;i++){ 34 if(s[i]==0) continue; 35 if(i==len) break; 36 if(len-sum[i]>=sum[i]) ans++; 37 else continue; 38 sum[i]--; 39 int mon=i-1; 40 int son=min(mon,len/2-sum[i]); 41 for(int j=son;j>=1;j--){ 42 ans+=f[mon][j]; 43 } 44 } 45 for(int i=len-1;i>=1;i--){ 46 for(int j=i/2-1;j>=1;j--){ 47 ans+=f[i-1][j]; 48 } 49 } 50 return ans+len-1; 51 } 52 int main(){ 53 // freopen("rndnum.in","r",stdin); 54 // freopen("rndnum.out","w",stdout); 55 st=read();nd=read(); 56 for(int i=0;i<=33;i++){ 57 f[i][0]=1; 58 } 59 for(int i=1;i<=33;i++){ 60 for(int j=1;j<=i;j++){ 61 f[i][j]=f[i-1][j-1]+f[i-1][j]; 62 } 63 } 64 printf("%d",solve(nd)-solve(st-1)); 65 return 0; 66 }
1266. 玉米田(cowfood.pas/c/cpp)
(File IO): input:cowfood.in output:cowfood.out
Time Limits: 1000 ms Memory Limits: 65536 KB Detailed Limits
Goto ProblemSet状压板子,我起了,一枪秒了,没什么好说的。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 int read(){ 5 int x=0,ff=1; 6 char c=getchar(); 7 while(!isdigit(c)){ 8 if(c=='-') ff=-1; 9 c=getchar(); 10 } 11 while(isdigit(c)){ 12 x=(x<<1)+(x<<3)+(c^48); 13 c=getchar(); 14 } 15 return x*ff; 16 } 17 const int N=15; 18 const int mod=1e8; 19 int m,n; 20 ll fix[N]; 21 ll f[N][1<<N]; 22 int main(){ 23 // freopen("cowfood.in","r",stdin); 24 // freopen("cowfood.out","w",stdout); 25 m=read();n=read(); 26 memset(f,0,sizeof(f)); 27 for(int i=1,num;i<=m;i++){ 28 for(int j=1;j<=n;j++){ 29 num=read(); 30 fix[i]=(fix[i]<<1)+num^1; 31 } 32 } 33 for(int i=0;i<(1<<n);i++){ 34 if((i&fix[1])||(i&(i<<1))||(i&(i>>1))) continue; 35 f[1][i]=1; 36 } 37 for(int i=2;i<=m;i++){ 38 for(int j=0;j<(1<<n);j++){ 39 if((j&(j<<1))||(j&(j>>1))||(j&fix[i-1])) continue; 40 for(int k=0;k<(1<<n);k++){ 41 if((j&k)||(k&fix[i])||(k&(k<<1))||(k&(k>>1))) continue; 42 f[i][k]=(f[i][k]+f[i-1][j])%mod; 43 } 44 } 45 } 46 ll ans=0; 47 for(int i=0;i<(1<<n);i++) ans=(ans+f[m][i])%mod; 48 printf("%lld",ans); 49 return 0; 50 }
1267. 路障(block.pas/c/cpp)
(File IO): input:block.in output:block.out
Time Limits: 1000 ms Memory Limits: 65536 KB Detailed Limits
Goto ProblemSet求次短路径。
拿另外一个dis2来保存次短的,考虑两种情况:
1.找到一条路径,发现可以更新最短路:
把这条路径给最短路,最短路的那条给次短路即可。
2.找到一条路径比最短路长但比次短路短:
给次短路即可。
注意次序。
1 #include<bits/stdc++.h> 2 #include<queue> 3 using namespace std; 4 int read(){ 5 int x=0,f=1; 6 char c=getchar(); 7 while(!isdigit(c)){ 8 if(c=='-') f=-1; 9 c=getchar(); 10 } 11 while(isdigit(c)){ 12 x=(x<<1)+(x<<3)+(c^48); 13 c=getchar(); 14 } 15 return x*f; 16 } 17 const int N=1e5+10; 18 int n,m; 19 struct edge{ 20 int to,next,w; 21 }e[N<<1]; 22 int head[N<<1],cnt; 23 void addedge(int from,int to,int w){ 24 e[++cnt]=(edge){to,head[from],w}; 25 head[from]=cnt; 26 } 27 int dis[N],dis2[N]; 28 struct node{ 29 int pos,dis; 30 bool operator < (const node&x)const{ 31 return dis>x.dis; 32 } 33 }; 34 priority_queue<node> q; 35 void dij(){ 36 memset(dis,0x3f,sizeof(dis)); 37 memset(dis2,0x3f,sizeof(dis2)); 38 dis[1]=0; 39 q.push((node){1,0}); 40 while(!q.empty()){ 41 node tmp=q.top(); 42 q.pop(); 43 int u=tmp.pos,w1=tmp.dis; 44 if(dis2[u]<tmp.dis) continue; 45 for(int i=head[u];i;i=e[i].next){ 46 int v=e[i].to,w=e[i].w+w1; 47 if(w<dis[v]){ 48 swap(dis[v],w); 49 q.push((node){v,dis[v]}); 50 } 51 if(dis[v]<w&&w<dis2[v]){ 52 dis2[v]=w; 53 q.push((node){v,dis2[v]}); 54 } 55 } 56 } 57 } 58 int main(){ 59 // freopen("block.in","r",stdin); 60 // freopen("block.out","w",stdout); 61 n=read();m=read(); 62 for(int i=1,x,y,z;i<=m;i++){ 63 x=read();y=read();z=read(); 64 addedge(x,y,z); 65 addedge(y,x,z); 66 } 67 dij(); 68 printf("%d",dis2[n]); 69 return 0; 70 }