百练1745:Divisibility

总时间限制: 
1000ms

内存限制: 
65536kB
描述
Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequence, thus deriving different arithmetical expressions that evaluate to different values. Let us, for example, take the sequence: 17, 5, -21, 15. There are eight possible expressions: 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 
We call the sequence of integers divisible by K if + or - operators can be placed between integers in the sequence in such way that resulting value is divisible by K. In the above example, the sequence is divisible by 7 (17+5+-21-15=-14) but is not divisible by 5.

You are to write a program that will determine divisibility of sequence of integers. 

输入
The first line of the input file contains two integers, N and K (1 <= N <= 10000, 2 <= K <= 100) separated by a space. 
The second line contains a sequence of N integers separated by spaces. Each integer is not greater than 10000 by it‘s absolute value. 
输出
Write to the output file the word "Divisible" if given sequence of integers is divisible by K or "Not divisible" if it‘s not.
样例输入
4 7
17 5 -21 15

样例输出

Divisible

题目分析:

  题目大意是给你一串数字,第一个数字不能改变,第2~n个数字可以变为相反数。判断这些数字的和是否能被k整除。

  因为1 <= N <= 10000, 2 <= K <= 100,因此普通的DFS必定会超时。

解决方案一:DFS 加上一定的剪枝处理

#include <cstdio>
#include <cstring>
int n,m;
bool jud = false;
int a[10001];
int v[10001][101];
void dfs(int cur, int x)
{
     if (jud)
         return;
     if (x==n-1&&cur%m==0)
     {
         jud=1;
         return;
     }
     else if (x==n-1)
         return;
     v[x][cur]=1;
     int plus=(cur+a[x+1])%m;
     if (x==n-2&&!plus)
     {
         jud=1;
         return;
     }
     else if (!v[x+1][plus])
         dfs(plus, x+1);
     int minus=(cur-a[x+1])%m;
     if (x==n-2&&!minus)
     {
         jud=1;
         return;
     }
     else if (!v[x+1][minus])
         dfs(minus, x+1);
 }
int main()
{
     scanf("%d %d", &n, &m);
     for (int i=0; i<n; i++)
         scanf("%d", &a[i]), a[i]=a[i]%m;
     dfs(a[0], 0);
     printf("%s\n", jud?"Divisible":"Not divisible");
     return 0;
}

解决方案二:dp,参照的poj Discuss区的代码

用dp[i-1][j] 表示前i-1行 出现过j 这个数;

#include<stdio.h>
#include<iostream>
using namespace std;
bool dp[10001][101];
long num[10001];
int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++)
    {
        int a;
        scanf("%d",&a);
        num[i]=a%k;
    }
    dp[0][0]=true;
 for(int i=1;i<=n;i++)
 {
     for(int j=k-1;j>=0;j--)
         if(dp[i-1][j])
         {
             dp[i][(j+num[i])%k]=1;
             dp[i][(k+j-num[i])%k]=1;
         }
 }
 if(dp[n][0])
     printf("Divisible\n");
 else
     printf("Not divisible\n");
return 0;
}

 方案三:Discuss中的,算是hash吧,代码比较简洁易懂,并且省空间!!!

#include <iostream>
using namespace std;
int main()
{
    int a[100],n,k,i;
       for(i=0;i<100;i++)
        a[i]=0;
       cin >> n >> k;
        int temp;
        cin >> temp;
        a[(temp%k + k)%k]=1;
       for(int i=2;i<=n;i++)
        {
            int b[100];
            for(int j=0;j<100;j++)
                b[j]=0;
            cin >> temp;
            for(int l=0;l<k;l++)//新输入的数与上轮存在的余数进行加和减运算
            {
                if(a[l])      //就是此处的l被我写成了i,最开始
                {
                    b[((l+temp)%k+ k)%k]=1;
                    b[((l-temp)%k+ k)%k]=1;
                }
            }
            for(int j=0;j<k;j++)
                a[j]=b[j];//某一轮输入结束后,所有存在的余数对应的a数组值取1,别的置0
        }
        if(a[0])cout << "Divisible" << endl;//最后一轮输入结束后,看是否有余数为0,即能整除的结果
        else cout << "Not divisible" << endl;

    return 0;
}
时间: 2024-08-29 21:28:13

百练1745:Divisibility的相关文章

18.06.30 POJ 百练1745:Divisibility

描述 Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequence, thus deriving different arithmetical expressions that evaluate to different values. Let us, for example, take the sequence: 17, 5, -21, 15

[OpenJudge] 百练2754 八皇后

八皇后 Description 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数.已经知道8皇后问题一共有92组解(即92个不同的皇后串).给出一个数b,要求输出第b个串.串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小. I

poj 百练 2765 八进制小数(精度问题)

2765:八进制小数 查看 提交 统计 提示 提问 总时间限制:  1000ms  内存限制:  65536kB 描述 八进制小数可以用十进制小数精确的表示.比如,八进制里面的0.75等于十进制里面的0.963125 (7/8 + 5/64).所有小数点后位数为n的八进制小数都可以表示成小数点后位数不多于3n的十进制小数. 你的任务是写一个程序,把(0, 1)中的八进制小数转化成十进制小数. 输入 输入包括若干八进制小数,每个小数占用一行.每个小数的形式是0.d1d2d3 ... dk,这里di

ACM/ICPC 之 递归(POJ2663-完全覆盖+POJ1057(百练2775)-旧式文件结构图)

POJ2663-完全覆盖 题解见首注释 //简单递推-三个米诺牌(3*2)为一个单位打草稿得出规律 //题意-3*n块方格能被1*2的米诺牌以多少种情况完全覆盖 //Memory 132K Time: 0 Ms #include<iostream> #include<cstring> #include<cstdio> using namespace std; int ans; //开始平铺 int Tiling(int n) { int sum = 0; if (n =

百练8216-分段函数-2016正式A题

百练 / 2016计算机学科夏令营上机考试 已经结束 题目 排名 状态 统计 提问 A:分段函数 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 编写程序,计算下列分段函数y=f(x)的值. y=-x+2.5; 0 <= x < 5 y=2-1.5(x-3)(x-3); 5 <= x < 10 y=x/2-1.5; 10 <= x < 20 输入 一个浮点数N,0 <= N < 20 输出 输出N对应的分段函数值:f

百练 1088 滑雪

“人人为我”的解法: dp[i][j]表示坐标为(i,j)的点开始下滑的最大长度. 则dp[i][j]为(i,j)周围四个点中比(i,j)低,且最大长度最大再加一的值 用结构体来储存一个点的坐标和高度,这样按高度从小到大排完序以后还不会丢失坐标的值 从小到大遍历所有的点,经过一个点(i,j)时,用递推公式求L(i,j). 一个小技巧: 将矩阵height四周的值赋值为INF,你可以想想这是滑雪场四周非常非常高的围墙. 这样就避免了数组越界的判断,而且不会影响正确结果(因为我们找的是滑雪场内部的最

百练6255-单词反转-2016正式B题

百练 / 2016计算机学科夏令营上机考试 已经结束 题目 排名 状态 统计 提问 B:单词翻转 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 输入一个句子(一行),将句子中的每一个单词翻转后输出. 输入 只有一行,为一个字符串,不超过500个字符.单词之间以空格隔开. 输出 翻转每一个单词后的字符串,单词之间的空格需与原文一致. 样例输入 hello world 样例输出 olleh dlrow 1 #include <iostream> 2 #i

POJ 1745 Divisibility (线性dp)

Divisibility Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 10598   Accepted: 3787 Description Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequence, thus deriving different arithmet

poj 1745 Divisibility(DP + 数学)

题目链接:http://poj.org/problem?id=1745 Description Consider an arbitrary sequence of integers. One can place + or - operators between integers in the sequence, thus deriving different arithmetical expressions that evaluate to different values. Let us, f