POJ Sticks1011解题报告

 1 //Sticks1011 By XieJiang 20170417
 2 /**
 3 *0.最小木棍的长度一定小于等于所有木棍长度之和,大于等于输入的最长的木棍
 4 *1.当Sticks[i]可用时,而Sticks[i-1]不可用且Sticks[i-1]=Sticks[i],Sticks[i]不可用,在DFS的过程中,
 5     如果当前木棒和前一个木棒长度相等,并且前一根木棒没有被使用,这说明此种长度的木棒不在此次遍历的解中,因此直接跳过
 6 *2.当组成木棒时,从大到小选取
 7 *3.组成木棒时,如果第一个选取的木棒不合适,就直接退出,表示整个木棒集合不合适
 8 *4.最终求出的木棒长度一定是总的木棒长的约数
 9 */
10 #include <iostream>
11 #include <algorithm>
12 using namespace std;
13 int gSum, gGoal, gN;
14 int gSticks[65], gUsed[65];
15 //归并排序,将输入数据按照从大到小的顺序排序
16 void MegSort(int A[], int T[], int left, int right){
17     int i, j, k, mid = (left + right) / 2;
18     if (left == right)return;
19     MegSort(A, T, left, mid);
20     MegSort(A, T, mid + 1, right);
21     for (i = mid; i >= left; i--)
22         T[i] = A[i];
23     for (j = 1; j <= right - mid; j++)
24         T[right - j + 1] = A[j + mid];
25     for (i = left, j = right, k = left; k <= right; k++){
26         if (T[j] <= T[i])
27             A[k] = T[i++];
28         else
29             A[k] = T[j--];
30     }
31 }
32 //深度搜索,找出将木棒进行配对:当前木棒已经配比的长度,木棒使用到的位置,已经配好的木棒数
33 bool DFS(int tCur, int tIndex, int tNum){
34     if (gGoal * tNum == gSum) return true;
35     int mi;
36     for (mi = tIndex; mi < gN; mi++){
37         if (mi && (gSticks[mi] == gSticks[mi - 1]) && (!gUsed[mi - 1])) continue;//1
38         if (gUsed[mi]) continue;//如果已经被使用,则不再使用
39         if (gSticks[mi] + tCur > gGoal)   continue;
40         gUsed[mi] = 1;
41         if (tCur + gSticks[mi] == gGoal){//当前这根木棒配完了
42             if (DFS(0, 0, tNum + 1))//搭配剩下的木棒
43                 return true;
44             gUsed[mi] = 0;
45             return false;
46         }
47         if (DFS(tCur + gSticks[mi], mi + 1, tNum))
48                 return true;
49         else{
50             gUsed[mi] = 0;
51             if (tCur == 0)
52                 return false;//3
53         }
54     }
55     return false;
56 };
57 int main(){
58     int i;
59     cin >> gN;
60     while (gN > 0){
61         gSum = 0; gGoal = 0;
62         for (i = 0; i < gN; i++){
63             cin >> gSticks[i]; gUsed[i] = gSticks[i];
64             gSum += gSticks[i];
65         }
66         MegSort(gSticks, gUsed, 0, gN - 1);
67         memset(gUsed, 0, sizeof(gUsed));
68         for (gGoal = gSticks[0]; gGoal <= gSum; gGoal++){//0 2
69             if (gSum % gGoal != 0)//4
70                 continue;
71             memset(gUsed, 0, sizeof(gUsed));
72             if (DFS(0, 0, 0)){
73                 cout << gGoal << endl;
74                 break;
75             }
76         }
77         cin >> gN;
78     }
79     return 0;
80 }
时间: 2024-08-05 15:22:15

POJ Sticks1011解题报告的相关文章

广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告

题目链接:http://poj.org/problem?id=3411 题目意思:N个city 由 m 条路连接,对于一条路(假设连接Cityia和 Cityb),如果从Citya 去 Cityb的途中,之前已经走过Cityc(可能会等于a),那么就可以交p的钱,否则之前未走过Cityc,就一定要交r 的路费啦. 注意,一个点可以被反复多次走,也就是可能构成环,虽然路走长了,但路费便宜了,这个问题要考虑到.还有就是剪枝啦:如果当前求得的路费比以前求得的答案要大,那就要回溯. mincost 明明

POJ 2230 解题报告

分析: 基础的欧拉路算法,变化在于要求每条边正向和反向各走一遍. 链式前向星构图,只要标记走过的单向边,边找边输出即可. code #include <iostream> #include <cstdio> using namespace std; struct node { int v, ne; } edge[100009]; int head[10009], vis[100009], cnt = 1; int n, m, x, y; void addedge (int u, i

POJ 2438 解题报告

分析: 2*n个小朋友,每个最多有n-1个"敌人",显然是存在哈密顿回路的. 预处理边,然后找哈密顿回路. code #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> using namespace std; #define pb push_back #define sz(a) (int

POJ 1001 解题报告 高精度大整数乘法模版

题目是POJ1001 Exponentiation  虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于错误的判断还不够严厉. 对边界情况的讨论其实应该是思维严密的表现,当然这并不能表明我写的一点错误都没有,只是多多分析一下还是很有好处的. #include <iostream> #include <fstream> #include <string> #include &l

poj分类解题报告索引

图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Journey poj1724 - ROADS(邻接表+DFS) BFS poj3278 - Catch That Cow(空间BFS) poj2251 - Dungeon Master(空间BFS) poj3414 - Pots poj1915 - Knight Moves poj3126 - Prim

POJ 1005 解题报告

题意就是,有一块半圆形区域,从0,0点开始向四周扩展,每年扩展50.0面积(单位统一不用考虑). 计算给定点在第几年结束之前被圆形区域覆盖. 我的思路: 1.计算以给定点到原点长度的半径做半圆的面积. 2.除以50.0,所得结果加1,就是所求 PI取3.14159265 #include<iostream> #include<string> using namespace std; int main() { double x, y; int n; const double PI =

poj图论解题报告索引

最短路径: poj1125 - Stockbroker Grapevine(多源最短路径,floyd) poj1502 - MPI Maelstrom(单源最短路径,dijkstra,bellman-ford,spfa) poj1511 - Invitation Cards(单源来回最短路径,spfa邻接表) poj1797 - Heavy Transportation(最大边,最短路变形,dijkstra,spfa,bellman-ford) poj2240 - Arbitrage(汇率问题,

poj 3020 Antenna Placement 解题报告

题目链接:http://poj.org/problem?id=3020 题目意思:首先,请忽略那幅有可能误导他人成分的截图(可能我悟性差,反正有一点点误导我了). 给出一幅 h * w 的图,  “ * ” 表示 point of interest,“ o ” 忽略之.你可以对 " * " (假设这个 “* ”的坐标是 (i, j))画圈,每个圈只能把它四周的某一个点括住(或者是上面(i-1, j) or 下面(i+1, j) or 左边(i, j-1)  or 右边(i, j+1))

poj 1469 COURSES 解题报告

题目链接:http://poj.org/problem?id=1469 题目意思:略 for 循环中遍历的对象要特别注意,究竟是遍历课程数P 还是 学生数N,不要搞混! 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 6 const int maxn = 300 + 5; 7 int match[maxn], map[maxn][maxn];