The 2020 ICPC Asia Macau Regional Contest

前言

vp

D.Artifacts

题意:阅读理解,字符串中提取出来对应的数据直接处理就好。

coding

void solve()
{
	double ATK=0,Cirt=5,DMG=50,ATK_Rate=0;
	for(int i=1;i<=25;i++){
		string s,temp;
		getline(cin,s);
		int t=0;
		for(int j=0;j<(int)s.size();j++){
			if(s[j]=='+')break;
			t=j;
		}
		string s1,s2;
		s1=s.substr(0,t+1);
		s2=s.substr(t+2);
		double num=0;
		int flag=0;
		for(int k=0;k<(int)s2.size();k++){
			if(s2[k]=='%')break;
			else if(s2[k]!='.'&&!flag)num=num*10+(s2[k]-'0');
			else if(s2[k]=='.')flag=k;
			else num+=pow(0.1,k-flag)*(s2[k]-'0');
		}
		if(s1=="ATK")ATK+=num;
		else if(s1=="ATK Rate")ATK_Rate+=num;
		else if(s1=="Crit Rate"){
			Cirt+=num;
			if(Cirt>=100)
				Cirt=100;
		}
		else if(s1=="Crit DMG Rate")DMG+=num;
		else continue;
	}
	ATK=1500*(1+0.01*ATK_Rate)+ATK;
	printf("%.10lf\n",ATK*(1-0.01*Cirt)+ATK*(1+DMG*0.01)*Cirt*0.01);
}

F. Fixing Networks

题意:n个点,构造分成c个集合,并且每个点的度数为d的图。
问:能否构造?如果能,那么每个点连接的点是什么?
思路:
1.d=0时,单点集合n=c
2.d=1时,双点集合c=n/2
3.d>1时,如果能够构成,那么每个集合至少含有d+1个点(构成环),最多连接的边数为nd/2,那么能够构成的条件一定是c(d+1)<n&&(nd%2==0)
4.能够构成时,将c-1个构成完全图,剩余的点再进行顺时针同一方向旋转。
设m=n-(c-1)
(d+1),取前m个点作为第c个图方便判断一些。

在这里插入图片描述

连接图时,类似这样按照一个方向进行连边,连接的是双向边,和相对的那个点开始连接。要注意的是,点数为奇数时会有两个点相对,那么从小的那个开始。

coding

void solve()
{
    ll n, c, d;
    scanf("%lld %lld %lld", &n, &d, &c);
    //特判完全图不是整数条边的情况和点数多了的情况
    if (((n * d) & 1) || (n < c * (d + 1)))
    {
        printf("No");
        return;
    }
    //特判单点集合和只有一条边的集合
    if (d == 0)
    {
        if (n == c)
        {
            printf("Yes");
        }
        else
            printf("No");
        return;
    }
    else if (d == 1)
    {
        if (n == c * 2)
        {
            printf("Yes\n");
            for (int i = 1; i <= n; i++)
            {
                if (i & 1)
                    printf("%d\n", i + 1);
                else
                    printf("%d\n", i - 1);
            }
        }
        else
            printf("No");
        return;
    }
    //特判都能够满足,就一定能够构成满足条件的情况
    //先构成c-1个完全图,剩下的点再进行链接
    printf("Yes\n");

    //完全图的点数为d+1,计算最后一个集合的点数
    int m = n - (c - 1) * (d + 1);
    vector<int> v[n + 1];
    //先连成环
    for (int i = 1; i <= m - 1;i++)
        v[i].push_back(i + 1), v[i + 1].push_back(i);
    v[1].push_back(m);
    v[m].push_back(1);
    //成环后度数-2
    int k = d - 2;
    for (int i = 1; i <= m;i++)
    {
        int l = i + m/ 2;
        l %= m;
        if (l == 0)
            l = m;
        //一定记得只有奇数点时采才用加入这条边
        if(k&1)v[i].push_back(l);
        for (int j = 1; j <= k / 2;j++)
        {
            l++;
            if (l > m)l = 1;
            v[i].push_back(l);
            v[l].push_back(i);
        }
    }
    for (int i = 1; i <= m;i++){
        sort(v[i].begin(), v[i].end());
        for(auto t:v[i])
            printf("%d ", t);
        printf("\n");
    }
    //c-1个完全图
    for (int i = 0; i < c - 1;i++){
        int l = i * (d + 1) + m + 1, r = (i + 1) * (d + 1) + m;
        for (int j = l; j <= r;j++){
            for (int k = l; k <= r;k++){
                if(j==k)
                    continue;
                printf("%d ",k);
            }
        printf("\n");
        }
    }
}

L. Random Permutation

模拟

void solve(){
    double n;
    cin >> n;
    double a = 1;
    for(int i=1;i<=n;i++)
    	 a *= 1.0 * i;
    a *= a;
    double s =  1.0;
    for(int i=1;i<=n;i++)
    	 s *= 1.0 * n;
    double y = 1.0 * a / s;
    printf("%.20lf", y);
}

总结

待补:
A.fft
G.博弈
I.Nim游戏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值