首页 > 代码库 > 哈尔滨理工大学2016新生赛D题

哈尔滨理工大学2016新生赛D题

陈月亮从小就热爱数学,这天老师讲到任何一个正整数N,我们可以很容易的找出N的所有因子,N1,N2,N3...,Nk,称N一共有k个因子(包含1和N本身)。

求出k的值这个问题对于陈月亮来说实在是太简单了,于是她想要求出N所有因子的因子个数(如N1可能包含n1个因子(包含1和N1本身),N2可能包含n2个因子,...,Nk可能包含nk个因子),然后计算出S的值:技术分享

第一行为一个整数T(T <= 10000),代表测试数据的组数。

接下来T行每行一个正整数N(N < 2 ^ 31)。

对于每组测试数据,输出S的值。

Sample Input

2

6

Sample Output

81

36 

#include <stdio.h>
#include <algorithm>
using namespace std;
const int size=100000;                //最大行列数
int a[size],b[size];                //分别保存行和与列和
int main(){
    int r,c,i,j;
    long long s,t;                    //枚举时比较的行和与列和总数
    while(scanf("%d%d",&r,&c)==2){//输入整数r,c直到文件结束
        for(i=0,s=0; i<r; i++){
            scanf("%d",&a[i]);        //输入行和
            s+=a[i];                    //累加行和
        }
        for(i=0,t=0; i<c; i++){
            scanf("%d",&b[i]);        //输入列和
            t+=b[i];                    //累加列和
        }
        if(s!=t){                        //如果行和与列和总数不相等
            printf("NO\n");            //则不可能有解
            continue;
        }
        sort(a,a+r);                    //行和排序
        sort(b,b+c);                    //列和排序
        for(i=j=0,t=s=0; i<c; i++){//从大到小枚举列和
            t+=b[c-i-1];                //当前已枚举的列和总数
            s+=r-j;                    //当前可用的行和总数
            while(j<r&&a[j]<i+1){    //如果某行和小于枚举列数
                s-=i+1-a[j];            //把行和总数多算出来的部分减去
                j++;
            }
            if(s<t) break;            //如果可用行和小于当前列和则不可能有解
        }
        printf(i==c?"YES\n":"NO\n");//输出答案
    }
    return 0;
}

 

哈尔滨理工大学2016新生赛D题