A - Right-Left Cipher
题意:给你一个按照:
1、先输入一个字符
2、在当前字符串后增加下一个字符
3、在当前字符串前增加下一个字符
4、在当前字符串后增加下一个字符
……
这个规律输入的字符串,求原字符串输入顺序
分析:直接逆推就行,字符串长度为奇和为偶时分开处理
#include<bits/stdc++.h>
using namespace std;
int main()
{
char s[1000],r[1000];
int j,mid,l;
cin>>s;
l=strlen(s);
if(l%2){
mid=l/2+1;
r[0]=s[mid-1];
j=1;
for(int i=1;i<=l/2;i++)
{
r[j++]=s[mid+i-1];
r[j++]=s[mid-i-1];
}
}else{
mid=l/2;
j=0;
for(int i=0;i<l/2;i++)
{
r[j++]=s[mid-i-1];
r[j++]=s[mid+i];
}
}
for(int i=0;i<l;i++)printf("%c",r[i]);
printf("\n");
return 0;
}
B - Div Times Mod
题意:给你n和k,让你找最小的正整数x,x满足(x/k)(x%k)=n
分析:从n的因子中找满足条件的
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,k,r=INT_MAX;
scanf("%d%d",&n,&k);
for(int i=1;i<=sqrt(n);i++){
if(!(n%i)){
if(i<k){
int x=i+n/i*k;
if(x<r)r=x;
}
if(n/i<k){
int x=n/i+i*k;
if(x<r)r=x;
}
}
}
printf("%d\n",r);
return 0;
}
C - Connect Three
题意:给定三个点,求出最小的点集使得三点可以在二维平面上联通
分析:任意坐标平面中的两点,有唯一长度的曼哈顿距离,如要使得路径上点集最小,那么就要使得两组点的曼哈顿距离所覆盖的点的重叠部分最多。所以我们找到x方向上的中点,那么路径就是由两边向中间靠拢的路径,y方向同理。
#include<bits/stdc++.h>
using namespace std;
int x[5] , y[5];
map <int , int> m;//后面通过排序来找中点,这里用map来保存三个点
int main()
{
for(int i = 0 ; i < 3 ; i++)
{
cin >> x[i] >> y[i];
m[x[i]] = y[i];
}
sort(x , x + 3);
sort(y , y + 3);
cout << y[2] - y[0] + x[2] - x[0] + 1 << endl;
for(int i = x[0] ; i < x[1] ; i++)
cout << i << " " << m[x[0]] << endl;
for(int i = x[2] ; i > x[1] ; i--)
cout << i << " " << m[x[2]] << endl;
for(int i = y[0] ; i <= y[2] ; i++)
cout << x[1] << " " << i << endl;
}
D - Minimum Diameter Tree
题意:给一棵树和树的总长度,让你分配边权,使树的直径最短(直径:从一个叶子结点到另一个叶子结点的简单路径的最大的权重之和)
分析:因为是从一个叶子结点到另一个叶子结点最长的一条路,所以假设从一个叶子结点到其他叶子结点长度都相同,将总权重平均分配给叶子结点即可。
#include<bits/stdc++.h>
using namespace std;
int v[100000+5];
int main()
{
int n,s,j,k,sum=0;
scanf("%d%d",&n,&s);
memset(v,0,sizeof(v));
for(int i=1;i<n;i++){
scanf("%d%d",&j,&k);
v[j]++;
v[k]++;
}
for(int i=1;i<=n;i++){
if(v[i]==1)sum++;
}
printf("%f\n",float(2.0*s/sum));
return 0;
}