9.24 AHSOFNU 校内模拟
Posted drizzly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了9.24 AHSOFNU 校内模拟相关的知识,希望对你有一定的参考价值。
//看起来养成了不好的风气 ,只更切菜杯?
好啦其实其他的好没有整理好... 而且切菜杯比较顺手
嗯下面进入正题 请各位倒着切题(lrb学长的特性)
个人卫生综合征
每天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。
Other:
比起下面可爱的题目绝对算是丧题了。
比较可惜的是好像暴力可以打一点点分... 不过时间都在跑t2的表上了
Solution:
建分层图。
把整张复制k次,跑dij。
//然而有思路的我还没打... 学长代码先贴上(待更新)
1 //学长代码...等待更新 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 #include <queue> 6 #define INF 0x3f3f3f3f 7 8 struct path 9 { 10 int to,v; 11 }; 12 struct node 13 { 14 int num,v; 15 bool operator <(const node &b) const 16 { 17 return v>b.v; 18 } 19 }; 20 std::vector<path> g[10001]; 21 std::priority_queue<node> q; 22 int m,n,k,ans; 23 int dist[10001][21]; 24 bool vis[10001][21]; 25 26 int getint() 27 { 28 int x=0,f=1; 29 char ch=getchar(); 30 while(ch<‘0‘||ch>‘9‘) 31 { 32 if(ch==‘-‘) f=-f; 33 ch=getchar(); 34 } 35 while(ch>=‘0‘&&ch<=‘9‘) 36 { 37 x=x*10+ch-‘0‘; 38 ch=getchar(); 39 } 40 return x*f; 41 } 42 43 int min(int a,int b) 44 { 45 return a<b?a:b; 46 } 47 48 void dij() 49 { 50 node now; 51 memset(dist,INF,sizeof(dist)); 52 memset(vis,false,sizeof(vis)); 53 dist[1][0]=0; 54 q.push((node){1,0}); 55 while(!q.empty()) 56 { 57 now=q.top(); 58 q.pop(); 59 int t1=now.num%(n+1),t2=now.num/(n+1); 60 vis[t1][t2]=true; 61 for(int i=0;i<int(g[t1].size());i++) 62 { 63 path t=g[t1][i]; 64 if((!vis[t.to][t2])&&dist[t.to][t2]>dist[t1][t2]+t.v) 65 { 66 dist[t.to][t2]=dist[t1][t2]+t.v; 67 q.push((node){t2*(n+1)+t.to,dist[t.to][t2]}); 68 } 69 if((!vis[t.to][t2+1])&&t2<k&&dist[t.to][t2+1]>dist[t1][t2]) 70 { 71 dist[t.to][t2+1]=dist[t1][t2]; 72 q.push((node){(t2+1)*(n+1)+t.to,dist[t.to][t2+1]}); 73 } 74 } 75 } 76 } 77 78 int main() 79 { 80 freopen("school.in","r",stdin); 81 freopen("school.out","w",stdout); 82 n=getint(),m=getint(),k=getint(); 83 for(int i=1;i<=m;i++) 84 { 85 int a=getint(),b=getint(),v=getint(); 86 g[a].push_back((path){b,v}); 87 g[b].push_back((path){a,v}); 88 } 89 dij(); 90 ans=INF; 91 for(int i=0;i<=k;i++) ans=min(ans,dist[n][i]); 92 printf("%d",ans); 93 return 0; 94 }
你的四边形已如风中残烛
LGL有一根长为n的木板。现在他想要把它砍成四段长度为整数的木板来做一个四边形,请问他有多少种不同的砍法?注意:四段长度为1、1、2、1和四段长度为1、2、1、1算两种砍法。
输入格式:
第一行为一个整数 n,表示木板的长度。
输出格式:
一个整数,不同的砍法数量。
样例输入 |
样例输出 |
6 |
6 |
样例解释:
1122,1212,1221,2112,2121,2211。
数据范围:
对于100%的数据:1<=n<=2500。
Other:
数学题。
想不出正解的只能好好打表。然而打表的优化不够,跑了一个多小时...(打表技巧有待提升)
机房大佬lzb一个表跑300s+就结束了(%%%)。
下面是lzb大佬的打表机。
1 //lzb的打表机 2 #include<cstdio> 3 using namespace std; 4 int main(){ 5 freopen("bll.out","w",stdout); 6 for(int n=0;n<=2500;n++){ 7 long long ans=0; 8 for(int i=1;i<=n/4;i++) 9 for(int j=i;j<=(n-i)/3;j++) 10 for(int k=j;k<=(n-i-j)/2;k++)if(n-i-j-k<i+j+k){ 11 if(i==j&&j==k&&k==n-i-j-k)ans++; 12 else if((i==j&&j==k)||(j==k&&k==n-i-j-k))ans+=4; 13 else if(i==j&&k==n-i-j-k)ans+=6; 14 else if(i==j||k==n-i-j-k||j==k)ans+=12; 15 else ans+=24; 16 } 17 printf("%lld,",ans); 18 } 19 }
Solution:
接下来是正解。
f[i][j]用来表示在i时分成j段的方案数,然后进行转移。
1 #include<cstdio> 2 #define MAXN 2505 3 #define Min(a,b) (a<b?a:b) 4 using namespace std; 5 int f[MAXN][5]; 6 int n,mid; 7 int main(){ 8 freopen("quad.in","r",stdin); 9 freopen("quad.out","w",stdout); 10 scanf("%d",&n); 11 mid=(n-1)>>1; 12 f[0][0]=1; 13 for(int i=1;i<=n;i++) 14 for(int j=1;j<=4;j++) 15 for(int k=1;k<=Min(mid,i);k++) f[i][j]+=f[i-k][j-1]; 16 printf("%d",f[n][4]); 17 return 0; 18 }
生命不息刷题不止
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。
Other:
坑题啊。蒟蒻先留坑。
Solution:
短
给出一张有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。
Solution:
题面很清楚的说出来是最短路啦~
对于次短路,我们可以用d[i]记录最短路,而最短路节点的上一个,即次短路的距离用d2[i]来记录。
次短路有两种情况:首先走di[i]到i然后从i到j,再走d2[j]到n;走d[i]到i,然后从i到j再到i,再走d2[i]到n。
然后直接跑dij就可以啦~
(机房大佬OMG_link SPFA被卡40嘿嘿嘿)
1 #include<cstdio> 2 #include<queue> 3 #include<map> 4 #include<vector> 5 #include<algorithm> 6 #define INF 0x7fffffff 7 #define Max_v 5005 8 using namespace std; 9 struct edge{int to,cost;}; 10 typedef pair<int,int> P; 11 int V,E; 12 vector <edge> G[Max_v]; 13 int d[Max_v]; 14 int d2[Max_v]; 15 void dijstra(int s){ 16 priority_queue<P,vector<P>,greater<P> >que; 17 fill(d,d+V,INF); 18 fill(d2,d2+V,INF); 19 d[s]=0; 20 que.push(P(0,s)); 21 while(!que.empty()){ 22 P p=que.top();que.pop(); 23 int v=p.second; 24 for(int i=0;i<G[v].size();i++){ 25 edge e=G[v][i]; 26 int dd=p.first+G[v][i].cost; 27 if(d[e.to]>d[v]+e.cost){ 28 d[e.to]^=dd;dd^=d[e.to];d[e.to]^=dd; 29 que.push(P(d[e.to],e.to)); 30 } 31 if(dd<d2[e.to] && dd>d[e.to]){ 32 d2[e.to]=dd; 33 que.push(P(d2[e.to],e.to)); 34 } 35 } 36 } 37 } 38 int main(){ 39 freopen("short.in","r",stdin); 40 freopen("short.out","w",stdout); 41 int x,y,w; 42 scanf("%d%d",&V,&E); 43 for(int i=0;i<E;i++){ 44 scanf("%d%d%d",&x,&y,&w); 45 x-=1;y-=1; 46 edge e; 47 e.to=y;e.cost=w;G[x].push_back(e); 48 e.to=x;e.cost=w;G[y].push_back(e); 49 } 50 dijstra(0); 51 printf("%d",d2[V-1]); 52 return 0; 53 }
以上是关于9.24 AHSOFNU 校内模拟的主要内容,如果未能解决你的问题,请参考以下文章