[BestCoder] Round #6

1001

http://acm.hdu.edu.cn/showproblem.php?pid=4981

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <cmath>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#define rd(x) scanf("%d",&x)
#define rd2(x,y)  scanf("%d%d",&x,&y)
#define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=1002;
int num[maxn];
int n;

int main()
{
    while(rd(n)!=EOF)
    {
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            rd(num[i]);
            sum+=num[i];
        }
        sort(num+1,num+1+n);
        if(1.0*sum/n>=num[(1+n)/2])
            printf("NO\n");
        else
            printf("YES\n");
    }
    return 0;
}

1002

http://acm.hdu.edu.cn/showproblem.php?pid=4982

题意为:

给出n,k,问能不能把n拆成k个不同的正整数相加,且其中k-1个数的和为完全平方数。

比如 n=22 ,k =4, 22可以拆成 1+5+6+10,且 1+5+10=4*4

BESTCODER主页上的题解:

PS:这道题目原来是要求输出一种可行方案的,所以下面题解是按照输出方案的思想搞的。

分析:

我们尝试枚举那个完全平方数 S,然后看能否将他拆分为 K-1 个数,并且不用到N-S

这一步可以用贪心+一次调整来搞定。为了保证 K-1 个数都不同,我们尝试尽量用 1,2,3...这些连续自然数来构造,如果 N-S 出现在这些数中,那么将 N-S 移除,再新加一个数。如果这样都不能拆分成 K-1 个数,那么这个 S 肯定不行。

现在考虑已经用上述方法拆分了,我们需要判断这个拆分是否可行。会产生问题的只有最后一个数,这个数可能和 N-S 一样,也可能出现在之前的序列。如果是出现在之前的序列,那么这个拆分也是不靠谱的。如果和 N-S 一样,那么分两种情况

1. N-S 曾出现在之前的序列,那么显然这个拆分也是不靠谱的

2. N-S 比倒数第二个数大,对于这种我们可以通过调整最后一个数和倒数第二个数的大小,来使得这个拆分成立,假设最后一个数为 a,倒数第二个为 b,只要 a-1,b+1 就好了。当然如果 a-1 = b+1 这个拆分也是不靠谱的这道题目就这样搞定了,其实没必要找所有的完全平方数,只要找小于 N 与 N 最接近的完全平方数就好了。

枚举出一个完全平方数,那么剩下的数就确定了,下面就开始判断剩下的那个数是否符合题意。

构造出完全平方数的k-1个数,从小到大,贪心,1,2,3.....

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <cmath>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#define rd(x) scanf("%d",&x)
#define rd2(x,y)  scanf("%d%d",&x,&y)
#define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int n,k;

bool ok(int s)
{
    int last=n-s;//最后一个数,k-1个数以外的那个数
    int k1=s,k2=1;//k1为k-1个数里面最后一个数,k2为倒数第二个数
    ///构造k-2个数
    for(int i=1;i<=k-2;i++)
    {
        if(k2==last)//与最后一个数相等,不可以
            k2++;
        k1-=k2;//这里写成k1=s-k2了
        if(k1<=k2)
            return false;
        k2++;
    }
    k2--;
    while(1)//调整k-1个数中的最后两个
    {
        if(k1<=k2)
            return false;
        if(k1!=last)
            return true;
        k1--;//
        k2++;
    }
}

int main()
{
    while(rd2(n,k)!=EOF)
    {
        int m=sqrt(n);
        if(m*m>=n)
            m--;
        bool yes=0;
        while(m)//枚举m,完全平方因子
        {
            if(ok(m*m))
            {
                yes=1;
                break;
            }
            m--;
        }
        if(yes)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

1003

http://acm.hdu.edu.cn/showproblem.php?pid=4983

解题思路:

gcd(n-a,n)*gcd(n-b,n)=n^k

要求有多少(a,b)满足上面的式子,1<=a,b<=n ,    1<=n,k<=10^9

gcd(n-a,n)<=n , gcd(n-b,n)<=n ,所以gcd(n-a,n)*gcd(n-b,n)<=n^2

当n=1时,只有(1,1)满足式子

当k>2时,有0个(a,b)满足式子

当k=2时,gcd(n-a,n)=n,gcd(n-b,n)=n, 只有(n,n)这种情况满足

当k=1时,gcd(n-a,n)*gcd(n-b,n)=n,也就是 gcd(n-a,n),gcd(n-b,n)均为n的因子

令gcd(n-a,n)=x,即x为n的一个因子

gcd(n-a,n)=x, gcd((n-a)/x, n/x)=1, 满足条件的(n-a)/x也就是 n/x的欧拉函数

所以枚举n的因子,两个因子的欧拉函数相乘,再累加就可以了,注意当x!=n/x时,欧拉函数相乘再*2

,因为a,b两个值可以倒换位置。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <cmath>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
#define rd(x) scanf("%d",&x)
#define rd2(x,y)  scanf("%d%d",&x,&y)
#define rd3(x,y,z) scanf("%d%d%d",&x,&y,&z)
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int n,k;
ll cnt;

int eular(int n)
{
    int ans=n;
    for(int i=2;i*i<=n;i++)
    {
        if(n%i==0)
        {
            ans-=ans/i;
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1) ans-=ans/n;
    return ans;
}

int main()
{
    while(rd2(n,k)!=EOF)
    {
        if(n==1||k==2)//注意这个语句和下面的if不能调换位置,
        {
            printf("1\n");
            continue;
        }
        if(k>2)
        {
            printf("0\n");
            continue;
        }
        ll ans=0;
        for(int i=1;i<=sqrt(1.0*n);i++)
        {
            if(n%i==0)
            {
                if(i!=(n/i))
                    ans+=eular(n/i)*eular(i)*2%mod;
                else
                    ans+=eular(n/i)*eular(i)%mod;
            }
        }
        printf("%I64d\n",ans%mod);

    }
    return 0;
}
时间: 2024-11-08 12:32:08

[BestCoder] Round #6的相关文章

BestCoder Round #91

传送门:http://acm.hdu.edu.cn/search.php?field=problem&key=BestCoder+Round+%2391&source=1&searchmode=source A题:给你n种字母,每种字母有个权值vali,共cnti个,现在让你在里面挑出任意数量的字符,组合成一个字符串,该字符串的权值的计算方式为val1*1+val2*2+--+valn*n,让你输出字符串最大的权值是多少.这题很容易会有一个错误的贪心,就是把val为负的舍去,然后v

BestCoder Round #65 (ZYB&#39;s Game)

ZYB's Game Accepts: 672 Submissions: 1207 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description ZYBZYBZYB played a game named NumberBombNumber BombNumberBomb with his classmates in hiking:a host keeps a

hdu5418 BestCoder Round #52 (div.2) Victor and World ( floyd+状压dp)

Problem Description After trying hard for many years, Victor has finally received a pilot license. To have a celebration, he intends to buy himself an airplane and fly around the world. There are n countries on the earth, which are numbered from 1 to

hdu 5163 Taking Bus (BestCoder Round #27)

Taking Bus                                                               Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 501    Accepted Submission(s): 203 Problem Description Bestland has a v

BestCoder Round #11 (Div. 2) 前三题题解

题目链接: huangjing hdu5054 Alice and Bob 思路: 就是(x,y)在两个參考系中的表示演全然一样.那么仅仅可能在这个矩形的中点.. 题目: Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 216    Accepted Submission(s): 166 Problem De

BestCoder Round #16

BestCoder Round #16 题目链接 这场挫掉了,3挂2,都是很sb的错误 23333 QAQ A:每个数字,左边个数乘上右边个数,就是可以组成的区间个数,然后乘的过程注意取模不然会爆掉 B:dp,dp[i][2]记录下第一长的LIS,和第二长的LIS,哎,转移的时候一个地方写挫掉了导致悲剧啊QAQ C:首先如果知道Nim游戏的,就很容易转化问题为,一些数字是否能选几个能否异或和为0,那么就是每个数字拆成40位,然后每一位异或和为0,这样就可以构造出40个方程,然后高斯消元求解,如果

BestCoder Round #11 (Div. 2) 题解

HDOJ5054 Alice and Bob Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 302    Accepted Submission(s): 229 Problem Description Bob and Alice got separated in the Square, they agreed that if they

BestCoder Round #9

BestCoder Round #9 题目链接 A:暴力枚举一个数字,就能求出另一个数字,for一遍即可 B:博弈,判断前n - 1个开头连续1的奇偶性即可 C:先预处理出每个点对应哪几个点,每次查询计算一次即可 代码: A: #include <cstdio> #include <cstring> #include <vector> #include <set> #include <algorithm> #include <cmath&g

hdu 4956 Poor Hanamichi BestCoder Round #5(数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4956 Poor Hanamichi Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 7    Accepted Submission(s): 4 Problem Description Hanamichi is taking part in

BestCoder Round #4 前两题 hdu 4931 4932

第一题太水了.. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int a[6]; 7 int main(){ 8 int cas; 9 scanf( "%d", &cas ); 10 while( cas-- ){ 11 for( int i = 0; i <