快速切题 poj1416 poj2676

Shredding Company
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 4115   Accepted: 2325

Description

You have just been put in charge of developing a new shredder for the Shredding Company Although a "normal" shredder would just shred sheets of paper into little pieces so that the contents would become unreadable, this new shredder needs to have the following unusual basic characteristics. 

1.The shredder takes as input a target number and a sheet of paper with a number written on it. 

2.It shreds (or cuts) the sheet into pieces each of which has one or more digits on it. 

3.The sum of the numbers written on each piece is the closest possible number to the target number, without going over it. 

For example, suppose that the target number is 50, and the sheet of paper has the number 12346. The shredder would cut the sheet into four pieces, where one piece has 1, another has 2, the third has 34, and the fourth has 6. This is because their sum 43 (= 1 + 2 + 34 + 6) is closest to the target number 50 of all possible combinations without going over 50. For example, a combination where the pieces are 1, 23, 4, and 6 is not valid, because the sum of this combination 34 (= 1 + 23 + 4 + 6) is less than the above combination's 43. The combination of 12, 34, and 6 is not valid either, because the sum 52 (= 12 + 34 + 6) is greater than the target number of 50. 
 
Figure 1. Shredding a sheet of paper having the number 12346 when the target number is 50


There are also three special rules : 

1.If the target number is the same as the number on the sheet of paper, then the paper is not cut. 

For example, if the target number is 100 and the number on the sheet of paper is also 100, then 

the paper is not cut. 

2.If it is not possible to make any combination whose sum is less than or equal to the target number, then error is printed on a display. For example, if the target number is 1 and the number on the sheet of paper is 123, it is not possible to make any valid combination, as the combination with the smallest possible sum is 1, 2, 3. The sum for this combination is 6, which is greater than the target number, and thus error is printed. 

3.If there is more than one possible combination where the sum is closest to the target number without going over it, then rejected is printed on a display. For example, if the target number is 15, and the number on the sheet of paper is 111, then there are two possible combinations with the highest possible sum of 12: (a) 1 and 11 and (b) 11 and 1; thus rejected is printed. In order to develop such a shredder, you have decided to first make a simple program that would simulate the above characteristics and rules. Given two numbers, where the first is the target number and the second is the number on the sheet of paper to be shredded, you need to figure out how the shredder should "cut up" the second number. 

Input

The input consists of several test cases, each on one line, as follows : 

tl num1 
t2 num2 
... 
tn numn 
0 0 

Each test case consists of the following two positive integers, which are separated by one space : (1) the first integer (ti above) is the target number, (2) the second integer (numi above) is the number that is on the paper to be shredded. 

Neither integers may have a 0 as the first digit, e.g., 123 is allowed but 0123 is not. You may assume that both integers are at most 6 digits in length. A line consisting of two zeros signals the end of the input. 

Output

For each test case in the input, the corresponding output takes one of the following three types : 

sum part1 part2 ... 
rejected 
error 

In the first type, partj and sum have the following meaning : 

1.Each partj is a number on one piece of shredded paper. The order of partj corresponds to the order of the original digits on the sheet of paper. 

2.sum is the sum of the numbers after being shredded, i.e., sum = part1 + part2 +... 

Each number should be separated by one space. 
The message error is printed if it is not possible to make any combination, and rejected if there is 
more than one possible combination. 
No extra characters including spaces are allowed at the beginning of each line, nor at the end of each line. 

Sample Input

50 12346
376 144139
927438 927438
18 3312
9 3142
25 1299
111 33333
103 862150
6 1104
0 0

Sample Output

43 1 2 34 6
283 144 139
927438 927438
18 3 3 12
error
21 1 2 9 9
rejected
103 86 2 15 0
rejected

感想:这真的是一道水题,我真的本来想只用5分钟过了的,结果果然用了一小时半
思路一开始的时候就没有搞清楚自己分解的数位到底是从高向低还是从低往高,
之后又想要借助之前的加和,但是忘记了每个数位对应的base在dfs过程之中修改过了,
之后是忘记了使用各位之和初始化ans就有可能压根不更新,然后打错了变量,
最后是:即使各位数字之加和为target,也不能保证就不重复,因为有0啊,

可想而知,要是没有测试数据,这道题死定了,这种思维不行啊,不断解决bug而不是思考的时候考虑全面

应用时:5 min
实际用时: 1h41min
思路:水题,我就直接从数据分析了,。。。。。。。。。。。
50 12346
关注的只有在何处切,这已经很明白了
用余数分解后得到 654321
设置数组vis,vis[i]代表在i之前切e.g: vis[1]=true;其余全是false;6 54321
vis[0]其实没什么用,就少写行代码,00000000 654321
error直接统计各位数加和就行,没有其他分割方式小于这个分割方式了(但是可能等于)
rejected注意不要想当然地判定。。。
输出反着输出就行
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int target,num,ans;
int bit[7],bt;
bool vis[7];
bool ansv[7];
bool flag;
void dfs(int s){
    if(s<0)return ;
    int sub=0,sum=0;
    vis[s]=true;
    for(int i=bt-1;i>=0;i--){
        sub=sub*10+bit[i];
        if(vis[i]){sum+=sub;sub=0;}
    }
    if(sum<=target&&target-sum<target-ans){
        ans=sum;
        for(int i=0;i<bt;i++){
            ansv[i]=vis[i];
        }
        flag=false;
    }
    else if(target-sum==target-ans){
        flag=true;
    }
    for(int i=s+1;i<bt;i++){
        dfs(i);
        vis[i]=false;
    }
}
int main(){
    while(scanf("%d%d",&target,&num)==2&&target&&num){
        bt=0;
        ans=0;
        memset(vis,0,sizeof(vis));
       // memset(bit,0,sizeof(bit));
        flag=false;
        if(num==target){
            printf("%d %d\n",num,num);
            continue;
        }
        while(num>0){
            bit[bt++]=num%10;
            num/=10;
        }
        for(int i=0;i<bt;i++){
            ans+=bit[i];
        }
        if(ans>target){
            printf("error\n");
            continue;
        }
        ans=0;
        dfs(0);
        if(flag){printf("rejected\n");continue;}
        printf("%d ",ans);
        for(int i=bt-1;i>=0;i--){
            printf("%d",bit[i]);
            if(ansv[i])printf(" ");
        }
        printf("\n");
    }
    return 0;
}
Sudoku
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 13739   Accepted: 6797   Special Judge

Description

Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of the cells are written decimal digits from 1 to 9. The other cells are empty. The goal is to fill the empty cells with decimal digits from 1 to 9, one digit per cell, in such way that in each row, in each column and in each marked 3x3 subsquare, all the digits from 1 to 9 to appear. Write a program to solve a given Sudoku-task. 

Input

The input data will start with the number of the test cases. For each test case, 9 lines follow, corresponding to the rows of the table. On each line a string of exactly 9 decimal digits is given, corresponding to the cells in this line. If a cell is empty it is represented by 0.

Output

For each test case your program should print the solution in the same format as the input data. The empty cells have to be filled according to the rules. If solutions is not unique, then the program may print any one of them.

Sample Input

1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107

Sample Output

143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127

感想:这是一道水题,所以没有起到锻炼思路的能力,但是还是有多处变量打错

思路:记录哪些不能用,从后面搜更快

应用时:3min

实际用时:46min

#include <cstdio>
#include <cstring>
#include <assert.h>
using namespace std;
bool block[9][10];
bool row[9][10];//i,x
bool col[9][10];//j,y
char org[9][10];
int game[9][9];
int cb(int x,int y){
    return x/3*3+y/3;
}
void printgame(){
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                    printf("%d",game[i][j]);
            }
            printf("\n");
        }
}
bool dfs(int x,int y){
    if(x<0)return true;
    if(game[x][y]!=0)return y?dfs(x,y-1):dfs(x-1,8);
        int numb=cb(x,y);
        for(int num=1;num<10;num++){
        if(block[numb][num]||row[x][num]||col[y][num])continue;
        game[x][y]=num;
      // printgame();
        block[numb][num]=row[x][num]=col[y][num]=true;
        if(y?dfs(x,y-1):dfs(x-1,8))return true;
        block[numb][num]=row[x][num]=col[y][num]=false;
        game[x][y]=0;
    }
    return false;
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        for(int i=0;i<9;i++){
            scanf("%s",org[i]);
        }
        memset(block,0,sizeof(block));
        memset(row,0,sizeof(row));
        memset(col,0,sizeof(col));
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                int t=org[i][j]-'0';
                game[i][j]=t;
                int numb=cb(i,j);
                block[numb][t]=true;
                row[i][t]=true;
                col[j][t]=true;
            }
        }
        assert(dfs(8,8));
        printgame();
    }
    return 0;
}

  

posted @ 2014-08-12 10:26  雪溯  阅读(173)  评论(0编辑  收藏  举报