校内模拟赛(20170924)
Posted ghostfly233
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了校内模拟赛(20170924)相关的知识,希望对你有一定的参考价值。
四校很丧,但是学长的题目更简单
lrb学长的题目为什么都要倒着切,不懂QAQ
————————————————我是分割线————————————————
T1:个人卫生综合征
每天BBS都要从家里经过城市中的一段路到学校刷五三。城市中一共有n个路口和m条双向道路,每条双向道路都连接着两个路口ai、bi且有一定的时间花费vi。BBS家编号为1,学校编号为n。今天,BBS由于个人卫生综合征导致他很迟才离开家,他想用膜法改变k条道路的长度使通过其的时间花费vi变为0。现在他问你改变道路长度之后他到学校的最小时间花费是多少?
输入格式:
第一行为三个整数n、m、k,接下来的m行每行三个整数ai,bi,vi,分别表示这条路连着的两个路口和通过其所用的时间。
输出格式:
一个整数,表示BBS到学校的最小时间花费。
样例输入 |
样例输出 |
4 4 1 |
1 |
样例解释:
更新3->4的道路,最短路线为1->3->4,用时为1+0=1。
数据范围:
对于100%的数据:1<=n<=10000,1<=m<=50000,1<=k<=20,1<=vi<=1000000。
————————————————我是分割线————————————————
emmm本次考试最丧的一题(但不是最坑的QAQ),但是其实也很好想,我们把整张图复制k份,然后跑dij就好了QAQ
#include<cstdio> #include<cstring> #include<queue> #define inf 0x3f3f3f3f #define MN 100005 using namespace std; int head[MN],dis[MN][25],num,n,m,k,x,y,v; bool vis[MN][25]; struct node{ int num,d; friend bool operator<(node a,node b){return a.d>b.d;} }; struct edge{ int to,next,w; }g[MN]; void ins(int u,int v,int w){g[++num].next=head[u];head[u]=num;g[num].to=v;g[num].w=w;} priority_queue<node> q; void dij(){ node now; memset(dis,inf,sizeof(dis)); memset(vis,0,sizeof(vis));dis[1][0]=0; q.push((node){1,0}); while(!q.empty()){ now=q.top();q.pop();//printf("%d\n",now); int t1=(now.num%n==0?n:now.num%n),t2=now.num/n;vis[t1][t2]=true; for(int i=head[t1];i;i=g[i].next){ if((!vis[g[i].to][t2])&&(dis[g[i].to][t2]>dis[t1][t2]+g[i].w)){ dis[g[i].to][t2]=dis[t1][t2]+g[i].w; q.push((node){t2*n+g[i].to,dis[g[i].to][t2]}); } if((!vis[g[i].to][t2+1])&&t2<k&&dis[g[i].to][t2+1]>dis[t1][t2]){ dis[g[i].to][t2+1]=dis[t1][t2]; q.push((node){(t2+1)*n+g[i].to,dis[g[i].to][t2+1]}); } } } } int main(){ freopen("school.in","r",stdin); freopen("school.out","w",stdout); scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&v),ins(x,y,v),ins(y,x,v); dij(); int ans=inf; for(int i=0;i<=k;i++)ans=min(ans,dis[n][i]); printf("%d\n",ans); fclose(stdin); fclose(stdout); }
————————————————我是分割线————————————————
T2:你的四边形已如风中残烛
LGL有一根长为n的木板。现在他想要把它砍成四段长度为整数的木板来做一个四边形,请问他有多少种不同的砍法?注意:四段长度为1、1、2、1和四段长度为1、2、1、1算两种砍法。
输入格式:
第一行为一个整数 n,表示木板的长度。
输出格式:
一个整数,不同的砍法数量。
样例输入 |
样例输出 |
6 |
6 |
样例解释:
1122,1212,1221,2112,2121,2211。
数据范围:
对于100%的数据:1<=n<=2500。
————————————————我是分割线————————————————
当然,我们可以写正解,不过你可以用一些奇特的技巧通过此题,比如:打表。。。。
下面贴上打表程序!
#include<cstdio> using namespace std; int main(){ freopen("bll.out","w",stdout); for(int n=0;n<=2500;n++){ long long ans=0; for(int i=1;i<=n/4;i++) for(int j=i;j<=(n-i)/3;j++) for(int k=j;k<=(n-i-j)/2;k++)if(n-i-j-k<i+j+k){ if(i==j&&j==k&&k==n-i-j-k)ans++; else if((i==j&&j==k)||(j==k&&k==n-i-j-k))ans+=4; else if(i==j&&k==n-i-j-k)ans+=6; else if(i==j||k==n-i-j-k||j==k)ans+=12; else ans+=24; } printf("%lld,",ans); } }
242.9秒出正解,贼快QAQ
好吧,正解我也说一下,就是枚举最小的和第二小的,然后通过数学方法O(1)统计剩下的两条边的情况。
#include<cstdio> int n,mid,ans=0; int main(){ freopen("quad.in","r",stdin); freopen("quad.out","w",stdout); scanf("%d",&n); mid=(n+1)/2-1; for(int i=1;i<=mid;++i){ for(int j=1;j<=mid;++j){ int sum=n-i-j; ans+=sum>mid?mid+mid-sum+1:sum-1; } } printf("%d",ans); return 0; }
————————————————我是分割线————————————————
T3:生命不息刷题不止
YYH有n道题要做。但是由于他上课做某些事,导致他一题都不会做,只好请LGL代打。LGL为了买自己心爱的坦克,他做第i题要收两笔钱:一笔在YYH叫他做题当天收,另外一笔在叫他做题的第二天收。YYH每天结束的时候都会把剩下的所有钱花光,然后再从父亲LRB处得到m元零花钱用来请LGL做题(也就是说,第一天的时候YYH是没有钱请LGL做题的,每一天用来请LGL做题所用的钱都是前一天LRB给的)。而且,YYH做的题目难度是循序渐进的:就算强如LGL,在做第i题之前也要先把第1到i-1题全部做完。请问YYH将所有题目做完并且把所有钱都付给LGL的最小天数。
输入格式:
第一行为两个整数m、n,接下来的n行每一行都有两个数ai和bi,分别表示LGL做第i题所收的两笔钱。
输出格式:
一个整数,表示最小天数。
样例输入 |
样例输出 |
100 5 |
6 |
样例解释:
第二天做1、2两题,第三天做3、4两题,第五天做5。在第六天的时候所有钱都付完。
数据范围:
对于100%的数据:1<=n<=300,1<=ai、bi<=m<=1000。
————————————————我是分割线————————————————
神奇的题目!最坑了!
看上去怎么都可以贪心。。但是其实不行的QAQ
比如说:
————————————————我是分割线————————————————
T4:短
给出一张有n个点和m条双向边的图,要求求出1到n的次短路的长度。一条边可以多次通过。
输入格式:
第一行为两个整数n和m。接下来的m行每行三个整数ai,bi,vi,分别表示这条路连着的两个点和他的长度。
输出格式:
一个整数,表示次短路的长度。
样例输入 |
样例输出 |
4 4 |
450 |
样例解释:
最短:1->2->4。
次短:1->2->3->4。
数据范围:
对于 100%的数据:1<=n、vi<=5000,1<=m<=100000。
————————————————我是分割线————————————————
暴力dij,不解释,本场最水的题目
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> #define MN 200005 #define M 5005 using namespace std; int head[M],d1[M],d2[M],n,m,num; struct e{ int to,next,w; }g[MN]; void ins(int u,int v,int val){g[++num].next=head[u];head[u]=num;g[num].to=v;g[num].w=val;} void insw(int u,int v,int w){ins(u,v,w);ins(v,u,w);} void swap(int &a,int &b){a^=b;b^=a;a^=b;} struct edge{ int to,value; edge(int to,int value):to(to),value(value) {} friend bool operator <(edge a,edge b){ return a.value>b.value; } }; priority_queue<edge>q; void dij(){ d1[1]=0;q.push(edge(1,0)); while(!q.empty()){ edge tmp=q.top();q.pop();if(tmp.value>d2[tmp.to])continue; for(int i=head[tmp.to];i;i=g[i].next){ int dd=tmp.value+g[i].w; if(dd==d1[g[i].to])continue; if(dd<d1[g[i].to]){ swap(dd,d1[g[i].to]); q.push(edge(g[i].to,d1[g[i].to])); } if(dd<d2[g[i].to]){ swap(dd,d2[g[i].to]); q.push(edge(g[i].to,d2[g[i].to])); } } } } int main(){ freopen("short.in","r",stdin); freopen("short.out","w",stdout); scanf("%d%d",&n,&m);memset(d1,0x3f,sizeof(d1));memset(d2,0x3f,sizeof(d2)); int x,y,val; for(int i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&val),insw(x,y,val); dij(),printf("%d\n",d2[n]); return 0; fclose(stdin); fclose(stdout); }
以上是关于校内模拟赛(20170924)的主要内容,如果未能解决你的问题,请参考以下文章