zoukankan      html  css  js  c++  java
  • UVa10036

    一 题意描述:

    给你N(1<=N<=10,000)个数字,你可以在它们之间的N-1个位置任意放“+”或“-”,放完之后,我们可以计算出表达式的值。 存不存在一种摆放方案使得最后表达式的值可以被K(1<=K<=100)整除。

    二 思路分析:

    1.基础知识巩固之负数除以正数的余数:

    由带余除法,任何一个整数n都可以表示成
    n=k*q+r 其中0<=r<q
    这里的r就是n除以q的余数
    通常记为
    n≡r(mod q)
    例如
    -9=(-2)*5+1
    则-9除以5的余数为1。为了保证余数为正,那对于一个负数s(s的绝对值小于k),要求它除以k的余数,那么我们可以用(s+k)%k求得余数。

    2.如何引入dp?

    我们用f[i][j]=1表示前i个数处理后所得余数为j(0<=J<K),如f[i-1][j]=1;

    那么对于第i个数(不妨设为正,任何情况下都取该数的绝对值)而言,有两种选择+或者-

    对于+:处理第i个数后的余数为(j+abs(a[i])%k)%k.那么f[i][(j+abs(a[i])%k)%k]=true;

    对于:处理第i个数后的余数为(j-abs(a[i])%k+k)%k.那么f[i][(j-abs(a[i])%k+k)%k]=true;

    如此往复,直到处理完最后一个数。

    下面开始判断:如果f[n-1][0]=true,说明这种情况可以被整除,输出visiable.否则输出disvisable。

    三 源码:

     1 #include <iostream>
     2 #include <fstream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 using namespace std;
     7 const int N = 10000 + 10;
     8 const int K = 100 + 10;
     9 bool f[N][K];
    10 int a[N];
    11 int main()
    12 {
    13     int n,k;
    14     int t;
    15     cin>>t;
    16     while(t--)
    17     {
    18         for(int i=0;i<n;i++)
    19         cin>>a[i];
    20         memset(f,false,sizeof(f));
    21         f[0][abs(a[0])%k]=true;
    22         for(int i=1;i<n;i++)
    23         {
    24             for(int j=0;j<k;j++)
    25             if(f[i-1][j])//如果上一次余数存在且为j
    26             {
    27                 f[i][(j+abs(a[i])%k)%k]=true;//(a+b)%k的余数等于( a%k +b%k )%k.
    28                 f[i][(j+k-abs(a[i])%k)%k]=true;//此处加k是为了避免余数为负值。
    29             }
    30         }
    31         if(f[n-1][0])  cout<<"Divisible"<<endl;
    32         else cout<<"Not divisible"<<endl;
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    chlick 在 blur 之后触发
    屏蔽运营商广告
    script标签清除缓存
    http-equiv 详解
    jqLite
    js 时间戳和转换-转载
    JS数组的常用方法
    js 前端实现文件流下载的几种方式
    解决兼容性的库
    移动端兼容性问题
  • 原文地址:https://www.cnblogs.com/khbcsu/p/3857928.html
Copyright © 2011-2022 走看看