[关闭]
@meredith233 2018-01-28T14:21:25.000000Z 字数 2806 阅读 916

2018/1/27

homework

A - The Necklace

题目大意:

一串由彩色珠子连接而成的项链散掉了,掉回地上的珠子判断有没有捡完,并且按顺序排列好(一个珠子两边有颜色,相邻珠子接触部分颜色应相同)。

解题思路:

可以转换为欧拉回路的问题,此处用基本法判断找出欧拉回路,并提前用每个点度数判断是否能构成欧拉回路。

AC代码:

  1. #include <cstdio>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <cstring>
  5. #include <queue>
  6. #include <vector>
  7. #include <stack>
  8. #define INF 0x3f3f3f3f
  9. #define MAX 1005
  10. using namespace std;
  11. int n,s;
  12. int ka;
  13. typedef pair<int,int> p;
  14. queue<p>ans;
  15. int mp[1005][1005];
  16. int into[1005];
  17. int up;
  18. void dfs(int u)
  19. {
  20. int f=0;
  21. for(int i=0;i<1001;i++){
  22. if(mp[u][i]!=0){
  23. mp[u][i]--;
  24. mp[i][u]--;
  25. dfs(i);
  26. f = 1;
  27. }
  28. if(f == 1){
  29. ans.push(make_pair(i,u));
  30. f = 0;
  31. }
  32. }
  33. }
  34. void solve()
  35. {
  36. dfs(s);
  37. int count1=0;
  38. stack<p>c;
  39. while(!ans.empty()){
  40. p ha,he;
  41. ha = ans.front();
  42. ans.pop();
  43. he.first = ha.second;
  44. he.second = ha.first;
  45. c.push(he);
  46. count1++;
  47. }
  48. for(int i=0;i<count1;i++){
  49. p ha;
  50. ha = c.top();
  51. c.pop();
  52. printf("%d %d\n",ha.first,ha.second);
  53. }
  54. }
  55. int main()
  56. {
  57. int t;
  58. ka = 0;
  59. scanf("%d",&t);
  60. while(t--){
  61. memset(mp,0,sizeof(mp));
  62. memset(into,0,sizeof(into));
  63. scanf("%d",&n);
  64. for(int i=0;i<n;i++){
  65. int a,b;
  66. scanf("%d%d",&a,&b);
  67. if(i == 0)
  68. s = a;
  69. mp[a][b]++;
  70. mp[b][a]++;
  71. into[a]++;
  72. into[b]++;
  73. }
  74. int flag = 0;
  75. for(int i=0;i<1001;i++){
  76. if(into[i]%2 != 0){
  77. flag = 1;
  78. break;
  79. }
  80. }
  81. printf("Case #%d\n",++ka);
  82. if(flag == 1){
  83. printf("some beads may be lost\n");
  84. }
  85. else{
  86. solve();
  87. }
  88. if(t!=0){
  89. printf("\n");
  90. }
  91. }
  92. return 0;
  93. }

B - Guess

题目大意:

给你一个上三角矩阵,矩阵内有'+','-','0'三种符号,对于Xij而言,指的是ai+...+aj的和大于0时为'+',小于0时为'-',等于零时为'0'。你要找出任一原数列。

解题思路:

将其转换为前缀和的形式,即Xij=sumj-sumi-1,将矩阵中每个符号对应的点进行连边,后用拓扑序排列,在枚举出值即可。

Tips

各值的绝对值大小必须小于等于10

AC代码:

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <cstring>
  4. #include <queue>
  5. #define MAX 105
  6. using namespace std;
  7. struct Edge{
  8. int next;
  9. int to;
  10. int val;
  11. }edge[MAX];
  12. int head[MAX],into[MAX];
  13. int mp[15][15];
  14. int n,cnt;
  15. int B[15];
  16. queue<int>ans;
  17. int ans1[15];
  18. void add(int u,int v,int w)
  19. {
  20. edge[cnt].to = v;
  21. edge[cnt].val = w;
  22. edge[cnt].next = head[u];
  23. head[u] = cnt++;
  24. }
  25. void topsort()
  26. {
  27. queue<int>q;
  28. int count1=0;
  29. for(int i=0;i<=n;i++){
  30. if(into[i]==0){
  31. q.push(i);
  32. into[i]--;
  33. }
  34. }
  35. while(!q.empty()){
  36. int s = q.front();
  37. q.pop();
  38. ans.push(s);
  39. count1++;
  40. for(int i=head[s];i!=-1;i=edge[i].next){
  41. int cur = edge[i].to;
  42. if(--into[cur] == 0){
  43. q.push(cur);
  44. }
  45. }
  46. }
  47. }
  48. int main()
  49. {
  50. int t;
  51. scanf("%d",&t);
  52. while(t--){
  53. cnt=0;
  54. memset(head,-1,sizeof(head));
  55. memset(into,0,sizeof(into));
  56. memset(B,0,sizeof(B));
  57. scanf("%d",&n);
  58. for(int i=1;i<=n;i++){
  59. for(int j=i;j<=n;j++){
  60. char c;
  61. scanf(" %c",&c);
  62. if(c == '+'){//前n项和关系
  63. add(i-1,j,1);
  64. into[j]++;
  65. mp[i][j]=1;
  66. mp[j][i]=1;
  67. }else if(c == '-'){
  68. add(j,i-1,1);
  69. into[i-1]++;
  70. mp[i][j]=-1;
  71. mp[j][i]=-1;
  72. }else{
  73. mp[i][j]=0;
  74. }
  75. }
  76. }
  77. topsort();
  78. int c=n;
  79. while(!ans.empty()){
  80. ans1[c--]=ans.front();
  81. ans.pop();
  82. }
  83. int pos=0;
  84. for(int i=1;i<=n;i++){
  85. if(ans1[i]==0){
  86. pos=i;
  87. B[pos]=0;
  88. break;
  89. }
  90. }
  91. for(int i=pos-1;i>=0;i--){
  92. int a=ans1[i],b=ans1[i+1];
  93. if(a>b)
  94. swap(a,b);
  95. a++;
  96. if(!mp[a][b]){
  97. B[ans1[i]]=B[ans1[i+1]];
  98. }
  99. else{
  100. B[ans1[i]]=B[ans1[i+1]]+1;
  101. }
  102. }
  103. for(int i=pos+1;i<=n;i++){
  104. int a=ans1[i-1],b=ans1[i];
  105. if(a>b)
  106. swap(a,b);
  107. a++;
  108. if(!mp[a][b]){
  109. B[ans1[i]]=B[ans1[i-1]];
  110. }
  111. else{
  112. B[ans1[i]]=B[ans1[i-1]]-1;
  113. }
  114. }
  115. printf("%d",B[1]);
  116. for(int i=2;i<=n;i++){
  117. printf(" %d",B[i]-B[i-1]);
  118. }
  119. printf("\n");
  120. }
  121. return 0;
  122. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注