• 【u028】数列的整除性


    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    对于任意一个整数数列,我们可以在每两个整数中间任意放一个符号'+'或'-',这样就可以构成一个表达式,也就可以计算出表达式的值。比如,现在有一个整数数列:17,5,-2,-15,那么就可以构造出8个表达式: 17+5+(-21)+15=16 17+5+(-21)-15=-14 17+5-(-21)+15=58 17+5-(-21)-15=28 17-5+(-21)+15=6 17-5+(-21)-15=-24 17-5-(-21)+15=48 17-5-(-21)-15=18 对于一个整数数列来说,我们能通过如上的方法构造出不同的表达式,从而得到不同的数值,如果该数值能够被k整除的话,那么我们就称该数列能被k整除。 在上面的例子中,该数列能被7整除(17+5+(-21)-15=--14),但不能被5整除。现在你的任务是,判断某个数列是否能被某数整除。


    【输入格式】

    第一行是一个整数m,表示有m个子任务。接下来就是m个子任务的描述。 每个子任务有两行。第一行是两个整数n和k(1<=n<=10000, 2<=k<=100),n和k中间有一个空格。n 表示数列中整数的个数;k就是需要你判断的这个数列是否能被k 整除。第二行是数列的n个整数,整数间用空格隔开,每个数的绝对值都不超过10000。

    【输出格式】

    输出文件应有m 行,依次对应输入文件中的m 个子任务,若数列能被k 整除则输出 "Divisible",否则输出 "Not divisible" ,行首行末应没有空格。

    【数据规模】

    Sample Input1

    2
    4 7
    17 5 -21 15
    4 5
    17 5 -21 15
    
    

    Sample Output1

    Divisible
    Not divisible
    
    【题解】
    这是一道动态规划的问题。
    设f[i][j]表示前i个数余数为j的情况是否出现
    f[i+1][(j+a[i+1])%k] = f[i+1][(j+a[i+1])%k] || f[i][j];
    f[i+1][|j-a[i+1]|%k] = f[i+1][|j-a[i+1]|%k] || f[i][j];
    然后一开始,如果输入的n个数字,出现负数,就直接取相反数改为正数就好。
    这里用到了同余率(反正就是(a+b-c)  % k == ((a+b) %k - c)%k 这样。因为我的题A掉了。所以这个等式应该是成立的。。
    然后对于每一个数字,只有加或减两张情况。
    然后之所以用余数来表示,是因为余数这个变量的k值不大,最大只有100.是适合用来作为状态的。
    如果f[n][0]为true,则表示这个数列能够被整除。
    【代码】
    #include <cstdio>
    #include <cstring>
    
    bool f[10001][101];
    int a[10001];
    int m, n,k;
    
    int main()
    {
    	scanf("%d", &m); //有m组数据
    	for (int i = 1; i <= m; i++)
    	{
    		memset(f, false, sizeof(f));
    		scanf("%d%d", &n, &k);
    		for (int i = 1; i <= n; i++)
    		{
    			scanf("%d", &a[i]); //如果是负数就直接改为正数就好。
    			if (a[i] < 0)
    				a[i] = -a[i];
    		}
    		f[1][a[1] % k] = true;//第一个数前的符号是不能改的。
    		for (int i = 2;i <= n;i++)
    			for (int j = 0;j <= k;j++)//其他数字的符号则可以改。
    				if (f[i - 1][j])
    				{
    					int temp = j + a[i];//加法的话temp不会出现负数所以不用加绝对值。
    					temp = (temp % k);
    					f[i][temp] = true;
    					temp = j - a[i];//减法就可能为负数了。要注意。
    					if (temp < 0)
    						temp = -temp;
    					temp = (temp % k);
    					f[i][temp] = true;//从前一个状态推到当前的状态。
    				}
    		if (f[n][0])//如果前n个数的余数为0.就表示这个数列能够被整除。
    			printf("Divisible
    ");
    		else
    			printf("Not divisible
    ");
    	}
    	return 0;
    }


  • 相关阅读:
    java连接mysql以及增删改查操作
    Django中ORM表的创建以及基本增删改查
    python链接mysql以及mysql中对表修改的常用语法
    Windows系统安装MySQL
    php 之 excel导出导入合并
    玄学基础
    ubuntu 17.10 安装QQ
    CI框架导入 excel
    atom插件安装
    excel怎么截取字符串
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632281.html
Copyright © 2020-2023  润新知