题目来源:http://poj.org/problem?id=1745
Divisibility
Time Limit: 1000MS |
Memory Limit: 10000K |
Description
Consider an arbitrary sequence of integers. Onecan place + or - operators between integers in the sequence, thus derivingdifferent arithmetical expressions that evaluate to different values. Let us,for example, take the sequence: 17, 5, -21, 15. There are eight possibleexpressions: 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 beplaced between integers in the sequence in such way that resulting value isdivisible 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 ofintegers.
Input
The first line of the input file contains twointegers, N and K (1 <= N <= 10000, 2 <= K <= 100) separated by aspace.
The second line contains a sequence of N integers separated by spaces. Eachinteger is not greater than 10000 by it's absolute value.
Output
Write to the output file the word"Divisible" if given sequence of integers is divisible by K or"Not divisible" if it's not.
Sample Input
4 7 17 5 -21 15
SampleOutput
Divisible
Source
-----------------------------------------------------
解题思路
动态规划(0-1背包)
题目本身的坑点在于C/C++里 -20%7 = -6而不是1,需要+7化成正数
值得注意的是之前一直听说但从来没有遇到过的”cin vs. scanf””int a[10001] vs. int *a = new int*[n]”前者速度慢于后者的情况终于发生了。
百练上的数据比较弱,用后面的写法也能过。poj上的数据比较严,一定要直接开固定大小的数组才能过,动态分配数组过不了;用cin也能过,但cin版本用时797ms, scanf版本用时297ms,差了500ms!太可怕了!
血泪教训:
1. 如果题目告诉了数据个数的上限,直接按上限开固定大小的数组;
2. 如果要从标准输入流中读取大量数据,用scanf不要用cin.
-----------------------------------------------------
代码
//E: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 #include<fstream> #include<iostream> #include<stdio.h> using namespace std; int main() { #ifndef ONLINE_JUDGE ifstream fin("tm201602E.txt"); int n,k,i,j; fin >> n >> k; int *num = new int[n]; for (i=0; i<n; i++) { fin >> num[i]; num[i] %= k; if (num[i]<0) // 防止出现负数 { num[i] += k; } } int **dp = new int*[n]; for (i=0; i<n; i++) { dp[i] = new int[k](); } // dynamic programming dp[0][num[0]] = 1; for (i=1; i<n; i++) { for (j=0; j<k; j++) { if (dp[i-1][j]) { dp[i][(j+num[i])%k] = 1; dp[i][(j-num[i]+k)%k] = 1; // 防止出现负数 } } } if (dp[n-1][0] == 1) { cout << "Divisible"; } else { cout << "Not divisible"; } delete[] num; for (i=0; i<n; i++) { delete[] dp[i]; } delete[] dp; fin.close(); #endif #ifdef ONLINE_JUDGE int n,k,i,j,tmp; cin >> n >> k; int num[10001]; // 开固定大小数组 for (i=0; i<n; i++) { cin >> num[i]; // 这里用cin也能过,但最好用scanf num[i] %= k; if (num[i]<0) { num[i] += k; } } int dp[10001][100] = {} ; // dynamic programming dp[0][num[0]] = 1; for (i=1; i<n; i++) { for (j=0; j<k; j++) { if (dp[i-1][j]) { dp[i][(j+num[i])%k] = 1; dp[i][(j-num[i]+k)%k] = 1; } } } if (dp[n-1][0] == 1) { cout << "Divisible"; } else { cout << "Not divisible"; } #endif }