CF每日一练(1.19)

A - Right-Left Cipher

CodeForces - 1085A

题意:给你一个按照:
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

CodeForces - 1085B 

题意:给你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

CodeForces - 1085C

题意:给定三个点,求出最小的点集使得三点可以在二维平面上联通

分析:任意坐标平面中的两点,有唯一长度的曼哈顿距离,如要使得路径上点集最小,那么就要使得两组点的曼哈顿距离所覆盖的点的重叠部分最多。所以我们找到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

CodeForces - 1085D

题意:给一棵树和树的总长度,让你分配边权,使树的直径最短(直径:从一个叶子结点到另一个叶子结点的简单路径的最大的权重之和)

分析:因为是从一个叶子结点到另一个叶子结点最长的一条路,所以假设从一个叶子结点到其他叶子结点长度都相同,将总权重平均分配给叶子结点即可。

#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;
}
posted @ 2019-01-20 13:12  长安大学ACM  阅读(143)  评论(0编辑  收藏  举报