• 2016中国大学生程序设计竞赛


    参考自:http://blog.csdn.net/queuelovestack/article/details/52205196#t30

    1001:A water problem

    题意:

    两个星球从宇宙大爆炸开始就产生了

    Xixi星球一年有73天,Haha星球一年有137天

    问宇宙大爆炸开始第N天是否是两个星球一年当中的第一天

    题解:

    就是求一个超大的数,长度是10000000,对137和73取余是否都等于0。

    你要知道乘法和加法对取余运算是没有任何影响的,那么假如这个数是456,那么先对73取余456%73 == (4%73)*(100%73)+(5%73)*(10%73)+(6%73)*(1%73) 取余173同理。

    那么我们就可以先预处理a[i],b[i]数组,存的分别是10^(i-1)%73和10^(i-1)%137的数,最后输入字符串,每个相乘,之后在相加,最后取余就好了。我写的先是int数组,居然爆了内存,之后幸好我还记得有short这么的类型,改完就可以了。

    之后又看了篇博客,写的好简单,但思路和我是差不多的,= = 还是我菜啊。。

    我的代码:

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int MAXN = 10000000 + 5 ;
    const short MO1 = 73 ;
    const short MO2 = 137 ;
    int K;
    char in[MAXN];
    short a[MAXN], b[MAXN];
    
    int main() {
        ll te = 1;
        for (int i = 0; i < MAXN; i++) {
            a[i] = te %= MO1;
            te *= 10;
        }
        te = 1;
        for (int i = 0; i < MAXN; i++) {
            b[i] = te %= MO2;
            te *= 10;
        }
        while (~scanf("%s", in)) {
            int an1 = 0, an2 = 0;
            int l = strlen(in);
            for (int i = 0; i < l; i++) {
                int d = in[i] - '0';
                an1 += d * a[l - i];
                an1 %= MO1;
                an2 += d * b[l - i];
                an2 %= MO2;
            }
            if (an1 == 0 && an2 == 0)printf("Case #%d: YES
    ", ++K);
            else printf("Case #%d: NO
    ", ++K);
        }
        return 0;
    }
    View Code

    别人的代码

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<iostream>
    //计算二进制中多少个1
    #define bitnum(a) __builtin_popcount(a)
    using namespace std;
    const int N = 10000005;
    const int M = 10005;
    const int inf = 1000000007;
    const int mod = 1000000007;
    char s[N];
    int main()
    {
        int ans1,ans2,p=1,i,k;
        while(~scanf("%s",s))
        {
            ans1=ans2=0;
            k=strlen(s);
            for(i=0;i<k;i++)
            {
                ans1=(ans1*10+s[i]-'0')%73;
                ans2=(ans2*10+s[i]-'0')%137;
            }
            if(!ans1&&!ans2)
                printf("Case #%d: YES
    ",p++);
            else
                printf("Case #%d: NO
    ",p++);
        }
        return 0;
    }
    View Code

    1004:Danganronpa

    题意:

    n种礼物,每种有a[i]个,所有的礼物可以作为普通礼物,也可以作为神秘礼物发放给孩子

    现在从第一个人开始,每人可以收到一个普通礼物和一个神秘礼物,相邻两个人不能收到相同的普通礼物,神秘礼物没限制,发完为止

    问最多有多少个人可以拿到两件礼物

    题解:

    这题数据有问题,写个sum/2就能过,做的时候就瞎想一通,不知道怎么的就a了,但看完别人博客发现写的不对,正确应该是这样的:

    暂时先不考虑普通礼物的限制

    那么最多有sum/2个人可以拿到两件礼物(sum为总的礼物件数,即a[1]+a[2]+……+a[n])

    那么在考虑普通礼物限制的情况下,我们肯定先要发放普通礼物,直到不能发或超过sum/2为止,这时多出来的礼物就作为神秘礼物补齐发到过普通礼物的孩子

    那么说明情况是不能发呢?因为相邻两人要获得不同的普通礼物

    所以我们可以借助优先队列,每次将队首的两种礼物取出来发放

    假设队首两种礼物的数量为a,b(a>b)

    那么可以有2*b个孩子拿到普通礼物,没发完的第一种礼物还剩a-b件,丢进优先队列重新来过

    最终得到答案ans,与sum/2取个小值就行了

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 10 + 5 ;
    int a[MAXN], n, K;
    void Solve() {
        ll sum = 0, ans = 0;
        priority_queue<int> priority;
        scanf("%d", &n);
        for (int i = 0; i < n; i++) scanf("%d", &a[i]), priority.push(a[i]), sum += a[i];
        int t = 0, te1 = 0, te2 = 0;
        while (!priority.empty()) {
            if (t) {
                te2 = priority.top();
                priority.pop();
                ans += te2 * 2;
                priority.push(te1 - te2);
            }
            else {
                te1 = priority.top();
                priority.pop();
            }
            t ^= 1;
        }
        printf("Case #%d: %lld
    ", ++K, min(sum / 2, ans));
    }
    int main() {
        int T;
        cin >> T;
        while (T--)
            Solve();
        return 0;
    }
    View Code
  • 相关阅读:
    透明PNG格式图片兼容IE6浏览器
    CSS英文单词强制换行
    未能加载文件或程序集“Oracle.DataAccess, Version=2.111.7.0, Culture=neutral, PublicKeyToken=89b483f429c47342”或它的某一个依赖项。试图加载格式不正确的程序
    使用IIS 无法命中Application_Start中的断点问题
    win7 x64 后蓝牙u盘搜索不到其他设备
    使用Html.BeginForm<T>后客户端脚本验证出错的问题
    为什么使用sealed修饰符
    vs2010调试时发生监视显示表达式为false,但却进入了if块中
    MicrosoftMvcJQueryValidation.js 启用客户端验证,form无法提交
    Jquery 操作页面中iframe自动跟随窗口大小变化,而不出现滚动条,只在iframe内部出滚动条
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5772865.html
Copyright © 2020-2023  润新知