正睿多校联盟训练Week5
Posted nopartyfoucaodong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正睿多校联盟训练Week5相关的知识,希望对你有一定的参考价值。
T1
Problem A. 阿瓦的海报
输入文件: poster.in
输出文件: poster.out
时间限制: 1 second
空间限制: 512 megabytes
阿瓦为了宣传她的影展,准备画一张海报张贴在幻想镇的各个角落。她为了让海报引人注目,已经在图案、背
景和排版上费了很大的工夫。
但这时她接到一个来自印刷厂的通知:印刷厂的纸不够了,本来答应给阿瓦定做的海报不能达到预期的尺寸。
印刷厂表示,剩下的纸最多能够承担每张海报的面积为 S。而阿瓦认为,海报的面积应当是越大越好,所以阿
瓦决定,就将每张海报的面积改成 S。
阿瓦认为,海报的面积越大,能表达的内容越多。海报的周长越小,视觉上的体验就越好。并且阿瓦还坚持,
海报的长和宽一定得是整数。请你告诉她,在面积确定的前提下,海报的周长最小是多少。
Input
第一行一个数 T,表示数据组数。
接下来 T 行,每行一个数 S,意义如题面中所述。
Output
输出共 T 行,对于每组数据输出一行表示最小周长。
Example
poster.in | poster.out |
5 5 6 7 1 1 | 12 10 16 4 4 |
Constraints
对于 30% 的数据, S ≤ 100。
对于 50% 的数据, S ≤ 105 。
对于 100% 的数据, S ≤ 109, T ≤ 5。
极水,我们搞一下模拟,找根号S,如果不是整数,就找离他最近的因数。
code
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 int T; 5 ll task(ll t) 6 { 7 ll ans=0,tmp=0; 8 stack<int>s; 9 for(int i=1;i*i<=t;i++) 10 if(t%i==0) tmp=i; 11 if(tmp*tmp==t) ans=4*tmp; 12 else ans=2*(tmp+t/tmp); 13 return ans; 14 } 15 int main() 16 { 17 scanf("%d",&T); 18 for(int i=1;i<=T;i++) 19 { 20 ll ask=0; 21 scanf("%lld",&ask); 22 printf("%lld ",task(ask)); 23 } 24 return 0; 25 }
T2
Problem B. 大战幻想珠
输入文件: bead.in
输出文件: bead.out
时间限制: 1 second
空间限制: 512 megabytes
烤乐滋又生日了!虽然过去了整整一年,可他还是对去年发生的炸弹事件充满阴影。于是决定不让来访的好友
们自带礼物。
但生日怎么能没有礼物呢?烤乐滋决定拿出他的幻想珠串来。幻想珠是一颗上面写着小写英文字母的珠子。有
些珠子自带神奇的魔力,上面写着一个"?",就表示这颗珠子可以表示任意一个小写英文字母。幻想珠串是长长的
一个个幻想珠首尾相连组成的串。烤乐滋决定,让每个朋友从这个珠串中挑选一段连续的串送给自己。
烤乐滋很喜欢回文(从前往后和从后往前读一样),于是他希望朋友挑选出的串都是回文的。比如"ababa"
和"acd?a" 都是回文的,而"a?d?c" 就不是回文的。
烤乐滋想要知道,整个幻想珠串中一共能挑选出多少个回文的子串。两个位置不同内容相同的子串我们也视
作是不同的子串。
Input
第一行一个数 n,表示幻想珠串的长度。
第二行一个有 n 个字符。只可能是小写字母或"?"。字符之间没有多余空格。
Output
一行一个数表示答案。
Example
bead.in | bead.out |
5 b?aba |
10 |
Constraints
对于 30% 的数据, n ≤ 10。
对于 50% 的数据, n ≤ 50。
对于 70% 的数据, n ≤ 300。
对于 100% 的数据, n ≤ 3000。
一道字符串题目。首先我们一定要注意,ans的初值设为n本身,因为一个字母本身也可构成一个回文串。
然后从n=3000的数据范围我们大概可以估计出用O(n方)的算法。
回文串的长度要么是奇数,要么是偶数。那么我们可以从每一个字母出发,找奇数长度的串和偶数长度的串是否为回文串。
细节:读入字符串的高端操作,“a+1",这样可以防止出现把末尾的空格读进。
code
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,l,r,ans; 4 char a[5000]; 5 int main() 6 { 7 scanf("%d",&n); 8 scanf("%s",a+1); 9 ans=n;//对于自己开始也是回文的 10 for(int i=1;i<=n;i++) 11 { 12 l=i-1;r=i+1; 13 //奇数长度的串 14 while(l>=1&&r<=n) 15 { 16 if(a[l]==a[r]||a[l]==‘?‘||a[r]==‘?‘) 17 {ans++;l--;r++;} 18 else break; 19 } 20 l=i;r=i+1; 21 //偶数长度的串 22 while(l>=1&&r<=n) 23 { 24 if(a[l]==a[r]||a[l]==‘?‘||a[r]==‘?‘) 25 {ans++;l--;r++;} 26 else break; 27 } 28 } 29 printf("%d",ans); 30 return 0; 31 }
T3
Problem C. 烤乐滋野餐
输入文件: picnic.in
输出文件: picnic.out
时间限制: 1 second
空间限制: 512 megabytes
烤乐滋今天没有犯错误,他心情就很好,于是他决定去幻想山野餐犒劳一下自己。但烤乐滋很懒,他不准备从
家里带任何食物,而是到幻想山上边买边吃。
幻想山上一共有 n 个便利店,每两个便利店都能够通过山路互相到达。整座山上一共有 n - 1 条山路,每条
山路连接着两个便利店,它们的长度可能不同。第 i 个便利店里能够供应 Pi 单位的食物。
烤乐滋是个大胃王,他希望吃到的东西越多越好,所以他很关心一路上经过的所有便利店的 P 值加和。但同
时他也很懒,不想走太多的路,所以他也同样很关心要走的长度。
烤乐滋定义一条简单路径(不经过重复点的路径)的愉悦值为:经过的所有便利店的食物供应和 ÷ 这条路径
经过的所有山路的长度和。
烤乐滋对于这天的计划有多种路径的选择,他每次都挑出一条路径,然后你需要回答烤乐滋,这条路径的愉悦
值为多少。
Input
第一行一个数 n,表示便利店个数。
第二行 n 个数,第 i 个数 Pi 表示第 i 家便利店的食物供应量。
接下来 n - 1 行,第 i 行三个数 ui, vi, wi。表示第 i 条山路连接 ui, vi 两家便利店,并且这条山路的长度为
wi。
接下来一行一个 m, 表示询问个数。
接下来 m 行,每行两个数 xi,yi。表示询问从便利店 xi 出发到便利店 yi 结束的这条路径的愉悦值。
Output
输出 m 行,对于每个询问输出对应的路径的愉悦值。
愉悦值以分数形式输出。分子与分母之间用"/" 隔开,并且要求是既约分数。比如你不能输出"2/4" 而要输
出"1/2"。注意当分母为 0 时,可直接输出" 路径上 P 的和/0"。
Example
picnic.in | picnic.out |
4 3 4 2 2 1 2 4 2 3 4 2 4 5 5 2 3 4 4 1 3 4 3 3 4 |
3/2 1/0 9/8 8/9 8/9 |
Constraints
对于 30% 的数据, n; m ≤ 10。
对于 50% 的数据, n; m ≤ 103。
对于 100% 的数据, n; m ≤ 105, 1 ≤ ui; vi; xi; yi ≤ n, 0 < wi; pi ≤ 103 。
一看起来就知道是图论。 还是一棵树 我们可以预处理出来每个点到遍历到根节点走的“wd""wb"(其实就是点权、边权辣...这个命名方法被L__A佬奶。。。)
然后求LCA。
gcd函数写错了有点难受。
code
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,m,tot,t,head[100005],supply[100005]; 4 int d[100005],f[100005][20]; 5 int wd[100005],wb[100005]; 6 struct node{ 7 int to,val,next; 8 }edge[200005]; 9 inline int read(){ 10 int a=0,t=1; char ch=getchar(); 11 while (ch<‘0‘ || ch>‘9‘){ 12 if (ch==‘-‘) t=-1; ch=getchar(); 13 } 14 while (ch>=‘0‘ && ch<=‘9‘){ 15 a=a*10+(ch-‘0‘); ch=getchar(); 16 } 17 return a*t; 18 } 19 void add(int x,int y,int z) 20 { 21 edge[++tot].to=y; 22 edge[tot].val=z; 23 edge[tot].next=head[x]; 24 head[x]=tot; 25 } 26 void pre_bfs() 27 { 28 wd[1]=supply[1];d[1]=1; 29 queue<int>q; 30 q.push(1); 31 while(q.size()) 32 { 33 int x=q.front();q.pop(); 34 for(int i=head[x];i;i=edge[i].next) 35 { 36 int y=edge[i].to; 37 if(d[y]) continue; 38 d[y]=d[x]+1; 39 f[y][0]=x; 40 wd[y]=wd[x]+supply[y]; 41 wb[y]=wb[x]+edge[i].val; 42 for(int j=1;j<=t;j++) 43 f[y][j]=f[f[y][j-1]][j-1]; 44 q.push(y); 45 } 46 } 47 } 48 int lca(int x,int y) 49 { 50 if(d[x]>d[y]) swap(x,y); 51 for(int i=t;i>=0;i--) 52 if(d[f[y][i]]>=d[x]) y=f[y][i]; 53 if(x==y) return x; 54 for(int i=t;i>=0;i--) 55 if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; 56 return f[x][0]; 57 } 58 int gcd(int a,int b) 59 { 60 return b ? gcd(b , a % b) : a; 61 } 62 int main() 63 { 64 n=read(); 65 t=log2(n)+1; 66 for(int i=1;i<=n;i++) supply[i]=read(); 67 for(int i=1;i<=n-1;i++) 68 { 69 int x=0,y=0,z=0; 70 x=read(),y=read(),z=read(); 71 add(x,y,z); 72 add(y,x,z); 73 } 74 m=read(); 75 pre_bfs(); 76 //for(int i=1;i<=n;i++) printf("%d ",wd[i]); 77 //for(int i=1;i<=n;i++) printf("%d ",wb[i]); 78 for(int i=1;i<=m;i++) 79 { 80 int x=0,y=0; 81 x=read(),y=read(); 82 int tmp=lca(x,y); 83 //cout<<"lca="<<tmp; 84 int ans2=wb[x]+wb[y]-2*wb[tmp]; 85 int ans1=wd[x]+wd[y]-2*wd[tmp]+supply[tmp]; 86 //printf("%d %d ",ans1,ans2); 87 if(ans2==0) 88 { 89 printf("1/0 "); 90 continue; 91 } 92 int cnt=gcd(ans1,ans2); 93 printf("%d/%d ",ans1/cnt,ans2/cnt); 94 } 95 return 0; 96 }
以上是关于正睿多校联盟训练Week5的主要内容,如果未能解决你的问题,请参考以下文章