zoukankan      html  css  js  c++  java
  • LETTers比赛第十二场解题报告

    LETTers比赛第十二场解题报告
    提交人:周杰
    第一题:
    典型的misere nim问题。
    可以通过拓展的nim游戏的证明来求解。单一nim游戏的证明是通过证明N和P态,然后证明必然的路径和终止状态的归属来证明的。这道题也是一样。
    具体证明可以参考09年国家集训队贾志豪的论文,或者参考我放在群共享里的game theory教材,或者下面这篇证明:
    http://blog.csdn.net/tdreamge/article/details/7227295。
    放上我的核心代码:
    int t;
    int num1, num2;
    int n;
    int data;
    int ans;

    int main (int argc, const char* argv[]) {

    scanf("%d", &t);
    For(i, 0, t) {
    scanf("%d", &n);
    ans = 0;
    num1 = 0; num2 = 0;
    For(j, 0, n) {
    scanf("%d", &data);
    if (data >= 2) num2++;
    if (data == 1) num1++;
    ans = ans ^ data;
    }
    if (ans == 0) {
    if (num2 >= 2) printf("Brother\n");
    if (num2 == 0) printf("John\n");
    } else {
    if (num2 == 0) printf("Brother\n");
    else if (num2 >= 1) printf("John\n");
    }
    }
    return 0;
    }

    第二题:这道题是很裸的dijkstra。。表示这道题是送AC的。
    代码不放了。

    第三题:Josephus问题。这道题因为只要求最后一个人的编号,所以可以递归求解。
    简单给出递归公式:f(n)= (f(n - 1)+ m) % n;
    最后输出f(n) + 1。
    代码:
    int ans[1000005];
    int n, d;

    int main (int argc, const char* argv[]) {

    while (scanf("%d %d", &n, &d) && (n || d)) {
    memset(ans, 0, sizeof(ans));
    ans[1] = 0;
    For(i, 2, n + 1) ans[i] = (ans[i - 1] + d) % i;
    printf("%d %d %d\n", n, d, ans[n] + 1);
    }
    return 0;
    }
    当然也可以不开ans数组,速度更快。

    第四题:暴力枚举。
    一个基本事实:一个数的因子是logn级别。
    接着可以发现复杂度不会超过nlogn*logn。
    参考代码:
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<set>
    #include<ctime>
    #define rep(i,n) for(int i=0;i<n;i++)
    using namespace std;
    const int maxn=100000+1;int n;
    vector<int> A[maxn];
    typedef vector<int>::iterator it;
    typedef vector<int>::reverse_iterator rit;
    typedef long long ll;
    void Cal(int x)
    {
    static int tmp[10000];
    int cnt=0;
    for(int i=1;i*i<=x;i++)if(x%i==0)
    tmp[cnt++]=i,tmp[cnt++]=x/i;
    sort(tmp,tmp+cnt);A[x].push_back(tmp[0]);
    for(int j=1;j<cnt;j++)
    if(tmp[j]!=tmp[j-1])
    A[x].push_back(tmp[j]);
    }
    int Ans[maxn*50];
    int main()
    {
    cin>>n;
    for(int i=1;i<n;i++) Cal(i);
    int ans=0;
    for(int a=1;a<n;a++)
    {
    int*end=Ans;
    for(int l=a;l<n;l+=a)
    {
    int r=n-l;
    for(rit i=A[r].rbegin();i!=A[r].rend();i++)
    if(*i>a) *(end++)=*i;
    else break;
    }
    if(Ans==end) continue;
    sort(Ans,end);
    ans++;
    for(int*i=Ans+1;i!=end;i++)
    if(*i!=*(i-1)) ans++;
    }
    cout<<ans<<endl;
    }

  • 相关阅读:
    体温上报APP2.2(第二阶段总结)
    体温上报APP2.1
    体温上报APP2.0
    体温上报APP1.2
    体温上报APP1.1
    个人作业——体温上报APP
    安卓学习14(ViewPager)
    安卓学习13(RecyclerView)
    安卓学习12(ListView)
    javascript获得给定日期的前一天的日期
  • 原文地址:https://www.cnblogs.com/LETTers/p/2504359.html
Copyright © 2011-2022 走看看