10.25~10.30任务题
来源:互联网 发布:java流程引擎框架 编辑:程序博客网 时间:2024/04/28 05:35
三道11年noip。
vijos1738,1740,1741
1738
地址:https://vijos.org/p/1738
做法:做法:没有做法,就是暴力大法师,一道代码题,打打下落、消除这些基本操作。数组从0开始写比1好写,真是神奇。
代码如下:
#include <bits/stdc++.h>#define M 30using namespace std;int n,m,i,j,t,k,y,tp,showski;int a[M][M],cnt[M],f[M][M],ans[M][M],mo[3]={0,1,-1};inline void ps(int aa[M][M],int bb[M][M],int cc[],int dd[]){ for(int i=0;i<5;i++) for(int j=0;j<7;j++) aa[i][j]=bb[i][j]; for(i=1;i<=t;i++) cc[i]=dd[i];}inline int ok(){ int tt=0;for(int i=1;i<=t;i++) if(cnt[i]) if(!tt||tt>cnt[i]) tt=cnt[i];return tt;}inline void fl(int x){ for(int i=0,j;i<7;i++) if(a[x][i]==0){ for(j=i+1;j<7&&a[x][j]==0;j++); if(j==7) return; else a[x][i]=a[x][j],a[x][j]=0; }}inline int C(){ int ff=0;for(int i=0;i<5;i++) for(int j=0;j<7;j++){ if(!a[i][j]) continue; if(i<3&&a[i][j]==a[i+1][j]&&a[i][j]==a[i+2][j]) f[i][j]=f[i+1][j]=f[i+2][j]=1; if(j<5&&a[i][j]==a[i][j+1]&&a[i][j]==a[i][j+2]) f[i][j]=f[i][j+1]=f[i][j+2]=1; }for(i=0;i<5;i++) for(j=0;a[i][j]&&j<7;j++) if(f[i][j]) ff=1,cnt[a[i][j]]--,a[i][j]=f[i][j]=0; for(i=0;i<5;i++) fl(i);return ff;}inline void dfs(int x){ int b[M][M],c[M];ps(b,a,c,cnt); for(int i=0;i<5;i++) for(int j=0;a[i][j]&&j<7;j++) for(int k=1;k<=2;k++) if(i+mo[k]>=0&&i+mo[k]<5){ if((mo[k]==-1&&a[i-1][j])||a[i][j]==a[i+mo[k]][j]) continue; ans[x][1]=i;ans[x][2]=j;ans[x][3]=mo[k]; swap(a[i][j],a[i+mo[k]][j]); for(fl(i),fl(i+mo[k]);C(););tp=ok(); if(x==n) if(tp==0) for(i=showski=1;i<=n;i++) printf("%d %d %d\n",ans[i][1],ans[i][2],ans[i][3]); if(showski==1) return; if(x!=n&&tp>2) dfs(x+1); ps(a,b,cnt,c); }}int main(){ for(scanf("%d",&n),i=0;i<5;i++) for(j=0;j<=7;j++){ scanf("%d",&y);if(y==0) break; a[i][j]=y;t=t>y?t:y;cnt[y]++; }dfs(1);if(!showski) printf("-1\n");return 0;}
1740
地址:https://vijos.org/p/1740
做法:如果你手算几个(或者你比较聪明的话),你应该就可以看出来检验值Yi是单调的,所以一眼二分。1s的时间,nlogn就过了,不写树状数组了。
代码如下:
#include <bits/stdc++.h>#define M 200010#define ll long longusing namespace std;ll n,m,s,i,j,x,y,a,b,t,ans;ll v[M],w[M],l[M],r[M],sum[M],cnt[M];inline ll cal(ll x){ for(t=cnt[0]=sum[0]=0,i=1;i<=n;i++){ sum[i]=sum[i-1];cnt[i]=cnt[i-1]; if(w[i]>=x) cnt[i]++,sum[i]+=v[i]; }for(i=0;i<m;i++) t+=(cnt[r[i]]-cnt[l[i]-1])*(sum[r[i]]-sum[l[i]-1]); return t;}int main(){ for(scanf("%lld%lld%lld",&n,&m,&s),i=1;i<=n;i++){ scanf("%lld%lld",&w[i],&v[i]); if(a>w[i]) a=w[i]; if(b<w[i]) b=w[i]; }for(i=0;i<m;i++) scanf("%lld%lld",&l[i],&r[i]); while(b-a>1){ ll mid=a+b>>1; if(cal(mid)>s) a=mid;else b=mid; }ans=min(abs(cal(a)-s),abs(cal(b)-s)); printf("%lld\n",ans);return 0;}
1741
地址:https://vijos.org/p/1741
做法:想到了一个极其暴力的贪心,看到vijos标签上写树形动规只觉得汗颜。只要存下车开到每个站点的时间和该站点最晚到的乘客的时间。每次寻找一段路,使得坐车的人最多,并且满足车比下一个站点最晚到的乘客到的晚,然后使劲用加速器。如果加速器太多了,直到车和最晚到的乘客同时到达下一个站点即可,然后寻找下一个合法的区间。最后扫一遍统计答案就好了。
#include <bits/stdc++.h>#define M 100010using namespace std;int showski=1,n,m,k,i,j,mx,xx,ans; int t[M],a[M],b[M],ar[M],la[M],d[M],tmp[M],sum[M];int main(){ for(scanf("%d%d%d",&n,&m,&k),i=1;i<n;i++) scanf("%d",&d[i]); for(i=1;i<=m;i++){ scanf("%d%d%d",&t[i],&a[i],&b[i]); sum[b[i]]++; if(t[i]>la[a[i]]) la[a[i]]=t[i]; }for(i=2;i<=n;i++) sum[i]+=sum[i-1]; while(showski){ for(ar[1]=0,i=2;i<=n;i++) ar[i]=max(ar[i-1],la[i-1])+d[i-1]; for(tmp[n]=n,i=n-1;i>=1;i--){ tmp[i]=tmp[i+1]; if(ar[i+1]<=la[i+1]) tmp[i]=i+1; }for(mx=1;!d[mx]&&mx<=n-1;) mx++; if(mx==n||k==0) break; for(i=mx+1;i<n;i++) if(d[i]&&sum[tmp[mx]]-sum[mx]<sum[tmp[i]]-sum[i]) mx=i; if(sum[tmp[mx]]-sum[mx]==0) break; for(xx=M-5,i=mx+1;i<=tmp[mx]-1;i++) xx=min(xx,ar[i]-la[i]); xx=min(xx,k);xx=min(xx,d[mx]);k-=xx;d[mx]-=xx; //cout<<k<<" "<<xx<<endl;system("pause"); }for(i=1;i<=m;i++) ans+=abs(ar[b[i]]-t[i]); printf("%d\n",ans);return 0;}
0 0
- 10.25~10.30任务题
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- 任务
- NOIP2016提高A组集训第1场 【JZOJ4824】配对游戏
- Linux 下 的 cc 和 gcc
- 通过多线程实现非阻塞TCP通信
- Python正则表达式
- 欢迎使用CSDN-markdown编辑器
- 10.25~10.30任务题
- 行内元素与块级元素分类
- XML的解析
- 第9周OJ实践 等比数列
- Nginx/LVS/HAProxy负载均衡软件的优缺点详解
- 【TensorFlow】学习率、迭代次数和初始化方式对准确率的影响
- dos命令
- Java中null或空值的判断处理
- pyhton 'gbk' codec can't encode character u'\xa0'