[关闭]
@sensitive-cs 2017-03-03T14:41:55.000000Z 字数 4860 阅读 776

萌新集中营第一期

题解


VIRTUAL FRIENDS
题意:略
思路:并查集
坑坑坑:bob 和 Bob不是一个名字,开始用tolower函数,我脑袋卡了,题也是。。。记住这个惨痛的教训,不要意淫一些事情找事做QAQ
代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <map>
  4. #include <string>
  5. #include <ctype.h>
  6. using namespace std;
  7. map<string,int> mmp;
  8. int par[200005];
  9. int ran[200005];
  10. int sum[200005];
  11. int fin(int x)
  12. {
  13. if (x == par[x])
  14. return x;
  15. else
  16. return par[x] = fin(par[x]);
  17. }
  18. void unit(int x,int y)
  19. {
  20. int rx = fin(x);
  21. int ry = fin(y);
  22. if (rx == ry) return;
  23. if (ran[rx] < ran[ry])
  24. {
  25. par[rx] = ry;
  26. sum[ry] += sum[rx];
  27. }
  28. else
  29. {
  30. par[ry] = rx;
  31. sum[rx] += sum[ry];
  32. if (ran[rx] == ran[ry]) ran[rx]++;
  33. }
  34. }
  35. int main()
  36. {
  37. int n;
  38. while (scanf("%d",&n) != EOF)
  39. {
  40. for (int l = 1;l <= n;l++)
  41. {
  42. int f;
  43. scanf("%d",&f);
  44. int k = 1;
  45. mmp.clear();
  46. memset(par,0,sizeof(par));
  47. memset(ran,0,sizeof(ran));
  48. memset(sum,0,sizeof(sum));
  49. for (int i = 1;i <= 200005;i++)
  50. {
  51. sum[i] = 1;
  52. par[i] = i;
  53. }
  54. for (int o = 1;o <= f;o++)
  55. {
  56. char a[25],b[25];
  57. scanf(" %s %s",a,b);
  58. if (!mmp[a])
  59. mmp[a] = k++;
  60. if (!mmp[b])
  61. mmp[b] = k++;
  62. int x = mmp[a],y = mmp[b];
  63. unit(x,y);
  64. int ans = 0;
  65. ans = fin(x);
  66. printf("%d\n",sum[ans]);
  67. }
  68. }
  69. }
  70. return 0;
  71. }

BAD HAIR-DAY
题意:
有一群羊,每一只羊有一定的高度,每只羊向右看可以看到严格小于她高度的羊的头,问每只羊一共可以看到多少羊头。
思路:
可以转换为每只羊可以被多少只羊看到。我们用一个栈来记录,每次入栈一个数,把这个数跟栈中的每一个数进行比较,直到遇到比她大的数为止,整个栈就成了一个单调栈。通过例子可以很清晰的明白。比如栈中有10 5 4,那么进去7的话,栈中最后的情况就是10和7,因为7比5和4大,5和4被遮住,所以就可以直接把5和4出栈,因为他们看不到7以后的羊了。
坑!!!!:题目给出的范围是10的9次方,所以当时就没有注意和是可以超出整数范围的,所以要用long long。
代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stack>
  4. using namespace std;
  5. int a[80005];
  6. stack<int> sta;
  7. int main()
  8. {
  9. int n;
  10. memset(a,0,sizeof(a));
  11. while (!sta.empty())
  12. sta.pop();
  13. scanf("%d",&n);
  14. for (int i = 1;i <= n;i++)
  15. scanf("%d",&a[i]);
  16. sta.push(a[1]);
  17. int pos = 2;
  18. long long ans = 0;
  19. while (pos <= n)
  20. {
  21. int t = a[pos];
  22. int in = sta.top();
  23. sta.pop();
  24. while (t >= in && !sta.empty())
  25. {
  26. in = sta.top();
  27. sta.pop();
  28. }
  29. if (t >= in)
  30. {
  31. sta.push(t);
  32. pos++;
  33. continue;
  34. }
  35. sta.push(in);
  36. ans += sta.size();
  37. sta.push(t);
  38. pos++;
  39. }
  40. printf("%I64d\n",ans);
  41. return 0;
  42. }

SLIDING WINDOW
题意:中文题意。
思路:线段树水过
坑:以后交poj,再也不用g++了
代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. using namespace std;
  5. int maxn[4000005];
  6. int minn[4000005];
  7. int a[1000005];
  8. int ans[1000005][2];
  9. int min(int a,int b)
  10. {
  11. return a >= b ? b : a;
  12. }
  13. int max(int a,int b)
  14. {
  15. return a >= b ? a : b;
  16. }
  17. void pushupa(int rt)
  18. {
  19. maxn[rt] = max(maxn[rt << 1],maxn[rt << 1|1]);
  20. }
  21. void pushupi(int rt)
  22. {
  23. minn[rt] = min(minn[rt << 1],minn[rt << 1|1]);
  24. }
  25. void builda(int l,int r,int rt)
  26. {
  27. if (l == r)
  28. {
  29. maxn[rt] = a[l];
  30. return;
  31. }
  32. int m = (l+r) >> 1;
  33. builda(l,m,rt << 1);
  34. builda(m+1,r,rt << 1|1);
  35. pushupa(rt);
  36. }
  37. void buildi(int l,int r,int rt)
  38. {
  39. if (l == r)
  40. {
  41. minn[rt] = a[l];
  42. return;
  43. }
  44. int m = (l+r) >> 1;
  45. buildi(l,m,rt << 1);
  46. buildi(m+1,r,rt << 1|1);
  47. pushupi(rt);
  48. }
  49. int querya(int ll,int rr,int l,int r,int rt)
  50. {
  51. if (ll <= l && r <= rr)
  52. {
  53. return maxn[rt];
  54. }
  55. int m = (l+r) >> 1;
  56. int ans1 = -1000000000,ans2 = -1000000000;
  57. if (ll <= m) ans1 = querya(ll,rr,l,m,rt << 1);
  58. if (rr > m) ans2 = querya(ll,rr,m+1,r,rt << 1|1);
  59. return max(ans1,ans2);
  60. }
  61. int queryi(int ll,int rr,int l,int r,int rt)
  62. {
  63. if (ll <= l && r <= rr)
  64. {
  65. return minn[rt];
  66. }
  67. int m = (l+r) >> 1;
  68. int ans1 = 1000000000,ans2 = 1000000000;
  69. if (ll <= m) ans1 = queryi(ll,rr,l,m,rt << 1);
  70. if (rr > m) ans2 = queryi(ll,rr,m+1,r,rt << 1|1);
  71. return min(ans1,ans2);
  72. }
  73. int main()
  74. {
  75. int n,k;
  76. while (scanf("%d%d",&n,&k) != EOF)
  77. {
  78. memset(a,0,sizeof(a));
  79. memset(maxn,0,sizeof(maxn));
  80. memset(minn,0,sizeof(minn));
  81. memset(ans,0,sizeof(ans));
  82. for (int i = 1;i <= n;i++)
  83. scanf("%d",&a[i]);
  84. builda(1,n,1);
  85. buildi(1,n,1);
  86. for (int i = 1;i <= n-k+1;i++)
  87. {
  88. ans[i][0] = queryi(i,i+k-1,1,n,1);
  89. ans[i][1] = querya(i,i+k-1,1,n,1);
  90. }
  91. for (int i = 1;i <= n-k+1;i++)
  92. if (i == 1) printf("%d",ans[i][0]);
  93. else printf(" %d",ans[i][0]);
  94. printf("\n");
  95. for (int i = 1;i <= n-k+1;i++)
  96. if (i == 1) printf("%d",ans[i][1]);
  97. else printf(" %d",ans[i][1]);
  98. printf("\n");
  99. }
  100. return 0;
  101. }

Sumsets
题意:
Given S, a set of integers, find the largest d such that a + b + c = d
where a, b, c, and d are distinct elements of S.
思路:
构造a+b,用二分,魔改pair,记录下标,因为数是不能重复的。
代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <algorithm>
  4. using namespace std;
  5. int a[1005];
  6. typedef pair<int,int> p;
  7. pair<p,int> pp[1000005];
  8. int b[1000005];
  9. bool cmp(pair<p,int> &a,pair<p,int> &b)
  10. {
  11. return a.second < b.second;
  12. }
  13. int main()
  14. {
  15. int n;
  16. while (scanf("%d",&n) == 1 && n)
  17. {
  18. memset(a,0,sizeof(a));
  19. memset(pp,0,sizeof(pp));
  20. memset(b,0,sizeof(b));
  21. for (int i = 0;i < n;i++)
  22. scanf("%d",&a[i]);
  23. sort(a,a+n);
  24. int sum = 0;
  25. for (int i = 0;i < n;i++)
  26. for (int j = 0;j < n;j++)
  27. {
  28. if (j == i) continue;
  29. pp[sum].second = a[i] + a[j];
  30. pp[sum].first.first = i;
  31. pp[sum].first.second = j;
  32. sum++;
  33. }
  34. sort(pp,pp+sum,cmp);
  35. for (int i = 0;i < sum;i++)
  36. b[i] = pp[i].second;
  37. int mark = -1;
  38. for (int i = n-1;i >= 0;i--)
  39. {
  40. for (int j = n - 1;j >= 0;j--)
  41. {
  42. if (j == i) continue;
  43. int *pos = NULL;
  44. int key = a[i] - a[j];
  45. pos = lower_bound(b,b+sum,key);
  46. int r = pos - b;
  47. if (*pos == key && pos != b+sum && pp[r].first.second != i && pp[r].first.first != j && pp[r].first.second != j && pp[r].first.first != i)
  48. {
  49. mark = i;
  50. break;
  51. }
  52. }
  53. if (mark != -1)
  54. break;
  55. }
  56. if (mark == -1) printf("no solution\n");
  57. else printf("%d\n",a[mark]);
  58. }
  59. return 0;
  60. }

Stripies
题意:
n只变形虫,他们中的任意两只遇到后质量会变成2*(sqrt(m1*m2)),问n只变形虫最后的质量最小是多少。
思路:
先把质量最大的拉出来续了,因为的续一次质量就会减少,我们要让质量越大的被续的次数越多才行,直到最后剩一个。而最理想的数据结构呢,就是优先队列了哦。
代码:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <queue>
  4. #include <cmath>
  5. using namespace std;
  6. priority_queue<double> pp;
  7. int main()
  8. {
  9. int n;
  10. while (~scanf("%d",&n))
  11. {
  12. while (!pp.empty()) pp.pop();
  13. for (int i = 1;i <= n;i++)
  14. {
  15. int t;
  16. scanf("%d",&t);
  17. pp.push(t);
  18. }
  19. while (pp.size() > 1)
  20. {
  21. double x = pp.top();
  22. pp.pop();
  23. double y = pp.top();
  24. pp.pop();
  25. double k = 2*sqrt(x*y);
  26. pp.push(k);
  27. }
  28. double ans = pp.top();
  29. printf("%.3f\n",ans);
  30. }
  31. return 0;
  32. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注