Codeforces Round #382 Div. 2【数论】

C. Tennis Championship(递推,斐波那契)

题意:n个人比赛,淘汰制,要求进行比赛双方的胜场数之差小于等于1.问冠军最多能打多少场比赛。
题解:
因为n太大,感觉是个构造。写写小数据,看看有没有结论。

  • 2 3 4 5 6 7 8 9 10 11 12 (人数)
  • 1 2 2 3 3 3 4 4 4 4 4 (比赛数)

发现比赛数的增长成斐波那契。维护一个前缀和即可。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll dp[100];
int main()
{
    ll n;
    memset(dp,0,sizeof(dp));
    dp[1]=1;
    dp[2]=2;
    for(int i=3;i<=95;i++)
    {
        dp[i]=dp[i-1]+dp[i-2];
    }
    for(int i=1;i<=95;i++)
    {
        dp[i]=dp[i-1]+dp[i];
    }
    cin>>n;
        n--;
        for(int i=1;i<=95;i++)
        {
            if(dp[i]>=n)
            {
                printf("%d\n",i);
                break;
            }
        }
    }

 

D. Taxes(数论知识)

题意:你有值为n的财富,你需要交税,缴税方式有两种,一是直接交n的最大因子(除自身)二是将n拆成若干份>=2的部分,交他们的最大因子和。问缴税的最小值。
题解:
两个定理。三素数定理:大于2的奇数都可以拆成三个素数和的形式
哥德巴赫猜想:任一大于2的偶数都可写成两个质数之和。
然后,判断一下,有一个cha点,如果n是奇数,n-2是素数,答案为2. 大素数判定小心re。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int pan(ll p)
{
    for(int i=2;i<=sqrt(p);i++)
    {
        if(p%i==0) return 0;
    }
    return 1;
}
long long n;
int main()
{
    scanf("%I64d",&n);
    if(pan(n))
    {
        cout<<1<<endl;
        return 0;
    }
    if(n==2)
    {
        cout<<1<<endl;
        return 0;
    }
    if(n%2)
    {
        if(pan(n-2))
            cout<<2<<endl;
        else
            cout<<3<<endl;
    }
    else
    {
        cout<<2<<endl;
        return 0;
    }
}

以上代码均参考别人博客,自己水平有限,被cha了一次,好多定理不会,好多算法没学,从今天起晚上的codeforces就不参加了,调整作息,刷书做题,抱大腿学算法,越努力,越幸运!

posted @ 2016-11-28 14:55  demianzhang  阅读(332)  评论(0编辑  收藏  举报