Feb
10
SGU 101 解题手记
2007 解题报告 Popularity: 1%
题目看完有似曾相识的感觉,不知道在什么地方见过这个题,直接就想到应该转化为欧拉路而不是哈密顿路。转化是这样的:以0-6这7个数字(注意是7个数字)为顶点,一张骨牌上作为一条边,即在骨牌上的两个数字之间连边。然后求一条欧拉路,再对照欧拉路,把骨牌的顺序排出来。
欧拉路要求所有的边都走一遍,这样所有的骨牌就被串起来了。算法复杂度
。
编码中遇到了一个问题,list的成员不能是数组。具体原因我没弄明白,只知道跟new有关。解决的办法是把数组封装到类里。
Sumbit 1: PE on 1。忘记在骨牌序号和+/-之间空格。
Sumbit 2: WA on 1。将C风格字符串错写成单引号,导致输出无效。
Sumbit 3: WA on 4。将“奇点有两个以上没有欧拉路”错写为“奇点有奇数个没有欧拉路”。
Sumbit 4: WA on 4。修改过程中计数奇点的变量初值错了。
Sumbit 5: WA on 4。仍然WA就很郁闷了,阅读Amber的程序后想起来了,我没有判断图是否连通……然后……发现了一处更晕的错误……我把翻转和不翻转都写的+号……这样都能过到4,真无语了。另外发现了一个不良习惯——我喜欢写i++,但按照C++ Primer的说法,没事儿要写++i,因为i++要额外做一项保存变量初值的工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | //AC #include <iostream> #include <list> using namespace std; struct domino { int d[3]; }; list<domino> dominoes; list<int> euler; int graph[7][7]; bool visited[7]; void build_euler(int v) { visited[v]=true; bool nopath=true; for (int i=0;i<=6;++i) while (graph[v][i]) { nopath=false; --graph[v][i]; --graph[i][v]; build_euler(i); } euler.push_back(v); } void print_ans() { int a=0,b=*euler.begin(); list<int>::iterator i=euler.begin(); ++i; for (;i!=euler.end();++i) { a=b; b=*i; for (list<domino>::iterator j=dominoes.begin();j!=dominoes.end();++j) if (a==j->d[1] and b==j->d[2]) { cout<<j->d[0]<<" +"<<endl; dominoes.erase(j); break; } else if (a==j->d[2] and b==j->d[1]) { cout<<j->d[0]<<" -"<<endl; dominoes.erase(j); break; } } } void build_dominoes_graph() { int n,i; domino t; cin>>n; for (i=1;i<=n;++i) { cin>>t.d[1]>>t.d[2]; t.d[0]=i; dominoes.push_back(t); ++graph[t.d[1]][t.d[2]]; ++graph[t.d[2]][t.d[1]]; } } inline void init() { memset(graph,0,sizeof(graph)/sizeof(int)); memset(visited,0,sizeof(visited)/sizeof(bool)); } int main() { init(); build_dominoes_graph(); int startp=-1,oddp=-1,notour=0,degree; for (int i=0;i<=6;++i) { degree=0; for (int j=0;j<=6;++j) degree+=(graph[i][j]); notour+=(degree & 1); if (degree) startp=i; else visited[i]=true; if (degree & 1) oddp=i; } if (notour>2) { cout<<"No solution"<<endl; return 0; } if (oddp!=-1) startp=oddp; build_euler(startp); bool visitedall=true; for (int i=0;i<=6;++i) visitedall&=visited[i]; if (!visitedall) { cout<<"No solution"<<endl; return 0; } /*debug*/ /*enddebug*/ print_ans(); return 0; } |
- https://www.briefdream.com/sgu-101/
- Tags:C++, DP, SGU, 字符串, 数组, 欧拉路, 算法
- (1)comments | leave a reply
- Trackback URI
November 28th, 2007 at 6:37 am
thanks for sharing :em69:
我没有判断图是否连通
Reply