zoukankan      html  css  js  c++  java
  • 【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;
    }


  • 相关阅读:
    vue form dynamic validator All In one
    TypeScript api response interface All In One
    closable VS closeable All In One
    macOS 如何开启 WiFi 热点 All In One
    vue css inline style All In One
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (下)
    牛腩新闻 59 整合添加新闻页 FreeTextBox 富文本编辑器,检测到有潜在危险的 Request.Form 值,DropDownList 的使用
    牛腩新闻 61尾声: error.aspx的使用 防止报错
    vs2010里面 新建网站里面的 asp.net网站 和 新建项目里面的 asp.net Web应用程序 的区别 (上)
    牛腩新闻 62:尾声续2 asp.net的编译和发布
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632281.html
Copyright © 2011-2022 走看看