codeforces 261 div2 virtual Participation

搞出来两个题,C题最后一刻想出了正解...码完正好时间到,后来交了一发过了。。。

总共过了3个题吧...

好像是组合数学专场

A. Pashmak and Garden:点击打开链接

这题就是说给你任意两个点的坐标,问这两个点是否是一个正方形的顶点,并输出另外两个点。

只要情况考虑周全就行。1Y

#include <iostream>
#include <stdio.h>

using namespace std;

int main()
{
    int x1,y1,x2,y2,x3,x4,y3,y4;
    cin>>x1>>y1>>x2>>y2;
    if(x1==x2){
        x3=x1+(y2-y1);
        x4=x3;
        y3=y1;
        y4=y2;
    }
    else if(y1==y2){
        x3=x1;
        x4=x2;
        y3=y1+(x2-x1);
        y4=y3;
    }
    else if(y2-y1==x2-x1||y2-y1==x1-x2){
        x3=x2;
        y3=y1;
        x4=x1;
        y4=y2;
    }
    else{
        printf("-1\n");
        return 0;
    }
    printf("%d %d %d %d\n",x3,y3,x4,y4);
    return 0;
}

B. Pashmak and Flowers:点击打开链接

这题是说,给你一串数字,最大值和最小值的差值为多少,一共有多少种组成这种差值的方案。

首先排个序,然后计算最大值个数cnt1和最小值个数cnt2。当最大值不等于最小值时,组合方案数为cnt1*cnt2。

当最大值等于最小值时,实际上就是从cnt1个数中选出2个的方案数C(n,2)=n*(n-1)/2。

注意这里可能会爆int,结果要用long long 保存

#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;

typedef  long long LL;

LL f[200010];

int main()
{
    LL n,fr,re,cnt1,cnt2;
    cin>>n;
    cnt1=cnt2=0;
    for(int i=0;i<n;i++){
        cin>>f[i];
    }
    sort(f,f+n);
    fr=f[0];
    re=f[n-1];
    for(int i=0;i<n;i++){
        if(f[i]==fr) cnt1++;
        else break;
    }
    for(int i=n-1;i>=0;i--){
        if(f[i]==re) cnt2++;
        else break;
    }
    if(fr==re){
        printf("%I64d %I64d\n",re-fr,(cnt1-1)*cnt1/2);
    }
    else{
        printf("%I64d %I64d\n",re-fr,cnt1*cnt2);
    }
    return 0;
}

C. Pashmak and Buses:点击打开链接

这题是说有n个小学生,k个bus,d天,小学生两两之间呆在同一个bus上的时间不能达到d天。输出一种方案。

最初的想法,贪心...先把小学生平分给k个bus,然后每个bus上看成有n/k(上取整)层小学生,每天移动一层就可以完成方案。。。

呵呵,天真,贪心只能过样例,第三个就wa了...

如果是这种方法的话,需要的天数和层数是一样的,然而事实上,我们的组合方法非常多..

不难发现,如果一共有k个bus,那么这一趟旅程选择乘车的方案数一共有k^d种,所以只要小学生的数量小于等于这个值就可以。

如何输出方案呢?k^d会让你联想到什么,没错,就是一个d位的k进制数,每次对这个数+1就可以得到一种新的方案

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

int ans[1001][1001];

int main()
{
    int n,k,d,ca,t;
    long long tmp;
    cin>>n>>k>>d;
    tmp=k;
    bool flag = false;
    for(int i=0;i<d;i++){
        if(n<=tmp){
           flag = true;
        }
        else{
            tmp*=k;
        }
    }
    if(flag){
        for(int i=0;i<d;i++){
            ans[i][0]=0;
        }
        for(int i=1;i<n;i++){
            ca=0;
            for(int j=0;j<d;j++){
                if(j==0){
                ca=1;
                }
                t=ans[j][i-1]+ca;
                ans[j][i]=t%k;
                ca=t/k;
            }
        }
        for(int i=0;i<d;i++){
            for(int j=0;j<n;j++){
                printf("%d ",ans[i][j]+1);
            }
            printf("\n");
        }
    }
    else {
        printf("-1\n");
    }
    return 0;
}

其他题dealing...



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值