看大佬做2017-WF,我这种菜鸡,只能刷刷水题,勉强维持生活。 赛后补补水题。

题目pdf链接,中文的,tls翻译的,链接在这里

个人喜欢在vjudge上面刷题。

E Need for Speed

题意:

有中文题意,我就不多说了,仪表盘会有一个固定偏差,求这个。

思路:

二分答案,进行判断,二分的上下限,我是 -1 到 1e8;一开始范围错了WA掉了。

  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <string.h>
  5. using namespace std;
  6. typedef long long int LL;
  7. const int INF=2e9+1e8;
  8. const int maxn=1e6+100;
  9. const double eps=1e-8;
  10. int di[maxn],si[maxn],n,T;
  11. bool judge(double mid)
  12. {
  13. double ans=0;
  14. for(int i=0; i<n; i++)
  15. {
  16. ans+=di[i]/(si[i]+mid);
  17. }
  18. // printf("mid=%lf ans=%lf\n",mid,ans);
  19. return ans>=T;
  20. }
  21. double solve(double l,double r)
  22. {
  23. double ans=-100000;
  24. while((l<=r)&&(r-l>eps))
  25. {
  26. double mid=(l+r)/2;
  27. //printf("l=%")
  28. // printf("mid=%lf flag=%d\n",mid,judge(mid));
  29. if(judge(mid)) l=mid;
  30. else r=mid;
  31. ans=mid;
  32. }
  33. return ans;
  34. }
  35. //#define JJ -0.508653377
  36. int main()
  37. {
  38. // printf("%lf\n",5/(3+JJ)+2/(2+JJ)+3/(6+JJ)+3/(1+JJ));
  39. scanf("%d%d",&n,&T);
  40. int l=INF;
  41. for(int i=0; i<n; i++)
  42. {
  43. scanf("%d%d",&di[i],&si[i]);
  44. l=min(si[i],l);
  45. }
  46. printf("%lf\n",solve(double(-l),100000000.));
  47. return 0;
  48. }

Problem I :Secret Chamber at Mount Rushmore

题目描述:

有一组转化关系,如果字符 a->b, b->c, 那么 a->c 也成立。问,给定一些关系,前面的字符串能否转为后面的字符串? yes:no

题目思路:

一开始预处理出,任意两点是否能到达。枚举每一个起点进行dfs。后面\(O(1)\)查询。

  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <string.h>
  5. #include <string>
  6. #include <queue>
  7. using namespace std;
  8. typedef long long int LL;
  9. const int INF=2e9+1e8;
  10. const int maxn=1e6+100;
  11. const double eps=1e-8;
  12. struct Node
  13. {
  14. char t;
  15. int next;
  16. }edge[maxn];
  17. int first[265],sz;
  18. void init()
  19. {
  20. memset(first,-1,sizeof(first));
  21. sz=0;
  22. }
  23. void addedge(char s,char t)
  24. {
  25. edge[sz].t=t,edge[sz].next=first[(int)s];
  26. first[(int)s]=sz++;
  27. }
  28. bool maze[265][265];
  29. bool vis[264];
  30. void dfs(int now,int to)
  31. {
  32. maze[now][to]=1;
  33. vis[to]=1;
  34. for(int i=first[to];i!=-1;i=edge[i].next)
  35. {
  36. int t=edge[i].t;
  37. if(vis[t]==0) dfs(now,t);
  38. }
  39. }
  40. int main()
  41. {
  42. init();
  43. int n,m;
  44. scanf("%d%d",&n,&m);
  45. for(int i=0;i<n;i++)
  46. {
  47. char s[5],t[5];
  48. scanf("%s%s",s,t);
  49. addedge(s[0],t[0]);
  50. }
  51. memset(maze,0,sizeof(maze));
  52. for(char i='a';i<='z';i++)
  53. {
  54. memset(vis,0,sizeof(vis));
  55. dfs(i,i);
  56. }
  57. while(m--)
  58. {
  59. char a[100],b[100];
  60. int lena,lenb;
  61. scanf("%s%s",a,b);
  62. lena=strlen(a),lenb=strlen(b);
  63. if(lena!=lenb) printf("no\n");
  64. else
  65. {
  66. bool flag=true;
  67. for(int i=0;i<lena;i++)
  68. {
  69. if(maze[(int)a[i]][(int)b[i]]==0)
  70. {
  71. flag=false;
  72. break;
  73. }
  74. }
  75. if(flag) printf("yes\n");
  76. else printf("no\n");
  77. }
  78. }
  79. return 0;
  80. }

题目链接:C - Mission Improbable

题目意思:

给你一个平面图代表每一个位置的箱子个数,问做多拿走多少个箱子,三视图不变?

解题思路:

看了题解慢慢懂的,问题在于求哪些箱子需要保留下来。才能保证三视图不变。首先我们想俯视图,只需要让有的地方留一个箱子即可。其次,正视图,侧视图。我们可以这样子思考,先不管正视图。我侧视图,选完了再说。那么侧视图需要保留的个数就是每行的最大值减一。

那么现在来考虑正视图。正视图应该如何选择才能使得选择最少并且满足条件? 如果侧视图选中了正视图的最大值那么正视图就不需要额外再选择。刚好,二分图匹配能解决,我们让二分图左边是行号,右边是列号。当某个位置既是行的最大值又是列的最大值,那么我们就在i行与j列之间建一条边。跑一遍匈牙利算法之后,匹配是最大的,意思就是让尽可能多的行列公用一个元素,之后对于无法公用的列那就让该列选择该列的最大值即可。

弱弱代码,仅供参考。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cctype>
  4. #include <cmath>
  5. #include <set>
  6. #include <map>
  7. #include <list>
  8. #include <queue>
  9. #include <deque>
  10. #include <stack>
  11. #include <string>
  12. #include <vector>
  13. #include <iostream>
  14. #include <algorithm>
  15. #include <stdlib.h>
  16. #include <time.h>
  17. using namespace std;
  18. typedef long long LL;
  19. const int INF = 2e9 + 1e8;
  20. const int MOD = 1e9 + 7;
  21. const double eps = 0.0000000001;
  22. void fre()
  23. {
  24. freopen("in.txt", "r", stdin);
  25. freopen("out.txt", "w", stdout);
  26. }
  27. #define MSET(a, b) memset(a, b, sizeof(a))
  28. #define fr(i, a, n) for (int i = a; i < n; i++)
  29. const int maxn = 150;
  30. int mat[maxn][maxn];
  31. int side[maxn], front[maxn];
  32. int G[maxn][maxn];
  33. int vis[maxn], link[maxn], n, m;
  34. int match(int x)
  35. {
  36. for (int i = 1; i <= m; i++)
  37. {
  38. if (!vis[i] && G[x][i])
  39. {
  40. vis[i] = 1;
  41. if (!link[i] || match(link[i]))
  42. {
  43. link[i] = x;
  44. return 1;
  45. }
  46. }
  47. }
  48. return 0;
  49. }
  50. int main()
  51. {
  52. scanf("%d%d", &n, &m);
  53. LL sum = 0, sub = 0;
  54. for (int i = 1; i <= n; i++)
  55. {
  56. for (int j = 1; j <= m; j++)
  57. {
  58. scanf("%d", &mat[i][j]);
  59. side[i] = max(side[i], mat[i][j]);
  60. front[j] = max(front[j], mat[i][j]);
  61. if (mat[i][j])
  62. sub++;
  63. sum += mat[i][j];
  64. }
  65. }
  66. for (int i = 1; i <= n; i++)
  67. {
  68. for (int j = 1; j <= m; j++)
  69. {
  70. if (mat[i][j] && side[i] == front[j])
  71. G[i][j] = 1;
  72. }
  73. }
  74. for (int i = 1; i <= n; i++)
  75. {
  76. memset(vis, 0, sizeof(vis));
  77. match(i);
  78. }//匹配
  79. for (int i = 1; i <= n; i++)
  80. if (side[i])
  81. sub += side[i] - 1; //统计侧视图
  82. for (int i = 1; i <= m; i++)
  83. if (!link[i] && front[i])
  84. sub += front[i] - 1; //把没匹配的额外加;
  85. printf("%lld\n", sum - sub);
  86. return 0;
  87. }

--------- D - Money for Nothing -------------

题目描述:

2017 World Final D,原本的题意就不说,我转化一下就是。给定两个点的集合set:\(A\);set:\(B\),任意在两个集合中各选一个,求最大的 \(max\left ( \left ( x_B - x_A \right )\times \left ( y_B-y_A \right ) \right )\);再和0取一下最大值(即为:最大值为负数输出0)。

解题思路:

参见了大佬的解法,可以把A集合的点和B集合的点都描在二维坐标系中。我们可以很容易发现,A集合中x相同的尽量取y小的,B集合中x相同的尽量取y较大的。那么我们可以将集合A按照 x的递增且y的递增 进行排序。那么我们从前往后遍历y只有变小才有可能比前一个的答案更优。否则就没意义,不保留那个元素。

对于集合B来讲,我们也对B集合按照A集合的方式进行排序。因为我们需要尽量y大的数,我们可以从后往前遍历,只有y变大了才可能更优;处理完后我们得到的A,B集合都是x严格递增y严格递减的序列;

根据官方题解:

假设P代表一个点,\(i < j\),\(P_i , P_j\)是A集合的点,\(k < l\),\(P_k , P_l\)是B集合的元素,我们定义\(f\left ( x,y\right )\)代表y点为右上角,x为左下角这个对角线所构成的矩形面积。画图可验证一个结论:

\(f\left ( i,k\right )+f\left ( j,l \right )\geq f\left ( i,l\right )+f\left ( j,k \right )\)

这个结论告诉我们,A集合中每个点的最优的与B的连线不会有相交除了端点处。有了这个结论分治法就可以解。

不知道如何分治,看这里。分治,快排算法类似的,选A集合中间的位置,找到A的最优解位置,以这个位置将原来的集合分为两个。再解决。具体看代码一目连然。

  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <math.h>
  7. #include <string>
  8. using namespace std;
  9. typedef long long int LL;
  10. #define MSET(a,b) memset(a,b,sizeof(a))
  11. const int maxn=1e6+10;
  12. struct Point
  13. {
  14. int x,y;
  15. }A[maxn],B[maxn],T[maxn];
  16. bool cmp(Point a,Point b) //x递增,y递增
  17. {
  18. if(a.x!=b.x) return a.x <b.x;
  19. return a.y<b.y;
  20. }
  21. LL ans;
  22. int dp[maxn];
  23. void dfs(int l,int r,int L,int R)
  24. {
  25. if(l>r||A[r].y>=B[L].y||A[l].x>=B[R].x) return ;
  26. int mid=(l+r)>>1,pos=0;
  27. int s=lower_bound(dp+L,dp+R+1,A[mid].x)-dp;
  28. LL mx=0;
  29. for(int i=s;i<=R;i++)
  30. {
  31. if(B[i].y<=A[mid].y) break;
  32. LL val=1ll*(B[i].y-A[mid].y)*(B[i].x-A[mid].x);
  33. if(val>mx) mx=val,pos=i;
  34. //if(val>ans) ans=val,pos=i;
  35. }
  36. ans=max(ans,mx);
  37. if(pos) dfs(l,mid-1,L,pos),dfs(mid+1,r,pos,R);
  38. else dfs(l,mid-1,L,R),dfs(mid+1,r,L,R);
  39. }
  40. int main()
  41. {
  42. int n,m;
  43. while(scanf("%d%d",&n,&m)+1)
  44. {
  45. for(int i=1;i<=n;i++) scanf("%d%d",&A[i].x,&A[i].y);
  46. for(int i=1;i<=m;i++) scanf("%d%d",&T[i].x,&T[i].y);
  47. sort(A+1,A+1+n,cmp);
  48. sort(T+1,T+1+m,cmp);
  49. int ia=1,ib=1;
  50. A[1]=A[1],B[1]=T[m];
  51. for(int i=2;i<=n;i++)
  52. if(A[i].y<A[ia].y) A[++ia]=A[i];
  53. for(int i=m-1;i>0;i--)
  54. if(T[i].y>B[ib].y) B[++ib]=T[i];
  55. reverse(B+1,B+1+ib);
  56. for(int i=1;i<=ib;i++) dp[i]=B[i].x;
  57. // for(int i=1;i<=ia;i++)
  58. // printf(">>> %d %d\n",A[i].x,A[i].y);
  59. // for(int i=1;i<=ib;i++)
  60. // printf(">>> %d %d\n",B[i].x,B[i].y);
  61. ans=0;
  62. dfs(1,ia,1,ib);
  63. printf("%lld\n",ans);
  64. }
  65. return 0;
  66. }

--------- F - Posterize -------------

题目描述:

就是求那个给出的公式,只考虑红色0-255像素值,给出每个颜色的像素点个数,要求把这些像素点变为最多k种像素值。求\(\sum _{i=1}^{n} \underset{1\leqslant i\leqslant k}{min}\left ( r_i-v_j\right )^2\)。每个像素原来的颜色与现在和它绝对值最小的元素的差值平方求和

解题思路:

dp的思想,0-255,时间复杂度:\(O(n^3)\)都可以,所以我们设 dp[i][j] :表示颜色分布0-i,变为最多j种颜色的答案。fx[i][j]:表示将颜色区间[i,j] 的颜色变为同样的某一种颜色的最小值。那么转移方程\(dp(i,j)=\underset{0\leq k\leq i}{min}(dp(k,j-1)+f(k+1,i))\)

code :

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cctype>
  4. #include <cmath>
  5. #include <set>
  6. #include <map>
  7. #include <list>
  8. #include <queue>
  9. #include <deque>
  10. #include <stack>
  11. #include <string>
  12. #include <vector>
  13. #include <iostream>
  14. #include <algorithm>
  15. #include <stdlib.h>
  16. #include <time.h>
  17. using namespace std;
  18. typedef long long LL;
  19. const int INF = 2e9 + 1e8;
  20. const int MOD = 1e9 + 7;
  21. const double eps = 0.0000000001;
  22. void fre()
  23. {
  24. freopen("in.txt", "r", stdin);
  25. freopen("out.txt", "w", stdout);
  26. }
  27. #define MSET(a, b) memset(a, b, sizeof(a))
  28. #define fr(i, a, n) for (int i = a; i < n; i++)
  29. const int maxn = 300;
  30. LL fx[maxn][maxn], dp[maxn][maxn];
  31. int red[maxn];
  32. void Min(LL &x, LL t)
  33. {
  34. if (t < x)
  35. x = t;
  36. }
  37. int main()
  38. {
  39. int n, k;
  40. scanf("%d%d", &n, &k);
  41. MSET(dp, 0x7f);
  42. MSET(fx, 0x7f);
  43. for (int i = 1; i <= n; i++)
  44. {
  45. int r, p;
  46. scanf("%d%d", &r, &p);
  47. red[r] = p;
  48. }
  49. for (int color = 0; color <= 255; color++)
  50. {
  51. for (int l = 0; l <= 255; l++)
  52. {
  53. LL num = 0;
  54. for (int r = l; r <= 255; r++)
  55. {
  56. num += 1ll * (r - color) * (r - color) * red[r];
  57. Min(fx[l][r], num);
  58. }
  59. }
  60. }
  61. //处理出,f[l][r];代表区间 l,r;
  62. for (int i = 0; i <= 255; i++)
  63. dp[i][1] = fx[0][i];
  64. for (int i = 0; i <= 255; i++)
  65. for (int j = 2; j <= k; j++)
  66. for (int t = 0; t < i; t++)
  67. Min(dp[i][j], dp[t][j - 1] + fx[t + 1][i]);
  68. cout << dp[255][k] << endl;
  69. return 0;
  70. }

World Finals 2017 (水题题解)的更多相关文章

  1. bzoj usaco 金组水题题解(2)

    续.....TAT这回不到50题编辑器就崩了.. 这里塞40道吧= = bzoj 1585: [Usaco2009 Mar]Earthquake Damage 2 地震伤害 比较经典的最小割?..然而 ...

  2. bzoj usaco 金组水题题解(2.5)

    bzoj 2197: [Usaco2011 Mar]Tree Decoration 树形dp..f[i]表示处理完以i为根的子树的最小时间. 因为一个点上可以挂无数个,所以在点i上挂东西的单位花费就是 ...

  3. bzoj usaco 金组水题题解(1)

    UPD:我真不是想骗访问量TAT..一开始没注意总长度写着写着网页崩了王仓(其实中午的时候就时常开始卡了= =)....损失了2h(幸好长一点的都单独开了一篇)....吓得赶紧分成两坨....TAT. ...

  4. Cmd2001的毒瘤水题题解

    怕不是我再不写题解这题就该成没人做也没人会的千古谜题了...... T1: 仔细分析题面,发现相同就是广义SAM上节点相同,相似就是广义SAM上为从根到某个点路径的前缀..直接SAM上跑从根开始,每个 ...

  5. 2006-2007 ACM-ICPC | POJ3380 POJ3384 POJ3385 水题题解

    // CF比赛链接:http://codeforces.com/gym/101650 // POJ链接:http://poj.org/searchproblem?field=source&ke ...

  6. LOJ6303:水题——题解

    https://loj.ac/problem/6303 题目来自LOJ. 就记一个公式,设f(n,k)为n!里分解得到的k(k为质数)的个数,则f(n,k)=f(n/k,k)+n/k. 证明很好证,显 ...

  7. leetcode水题题解

    344. Reverse String Write a function that takes a string as input and returns the string reversed. E ...

  8. CODE FESTIVAL 2017 qual B B - Problem Set【水题,stl map】

    CODE FESTIVAL 2017 qual B B - Problem Set 确实水题,但当时没想到map,用sort后逐个比较解决的,感觉麻烦些,虽然效率高很多.map确实好写点. 用map: ...

  9. PAT甲题题解-1011. World Cup Betting (20)-误导人的水题。。。

    题目不严谨啊啊啊啊式子算出来结果是37.975样例输出的是37.98我以为是四舍五入的啊啊啊,所以最后输出的是sum+0.005结果告诉我全部错误啊结果直接保留两位小数就可以了啊啊啊啊 水题也不要这么 ...

随机推荐

  1. Linux Perf Probes for Oracle Tracing

    Luca Canali on 21 Jan 2016 Topic: this post is about Linux perf and uprobes for tracing and profilin ...

  2. ios 联网 在mac机器上进行抓包

    Remote Virtual Interface在使用Mac抓取iPhone数据包中介绍了两种方式在Mac电脑上抓取iPhone上的数据包,一是使用Mac的网络共享功能将Mac的网络通过WiFi共享给 ...

  3. [Android] 环境配置之Android Studio开发NDK

    分类:Android环境搭建 (14351)  (20) ========================================================作者:qiujuer博客:bl ...

  4. Keras学习

    参加比赛用到了keras,虽然之前用tensorflow,但是感觉tensorflow的确不太友好,api比较难读,然后就学习keras使用 随着深入,发现keras的api确实比较友好 跑了一些ex ...

  5. PS 基础知识 .pat文件如何使用

    我下了pat文件单打不开,也下了ps 匿名 回答:5 人气:7 解决时间:2009-05-25 12:48 满意答案 将你下载的pat文件放到下面文件夹内,(这是默认安装地址),重新打开Photosh ...

  6. Toolbar的使用.md

    1.什么是Toolbar Toolbar是在Android5.0时出现的一个新控件,其目的用于取代Actionbar,它与Actionbar最大的差别就是Toolbar使用更加灵活.自由,而且Tool ...

  7. ARP协议(1)什么是ARP协议

    这是最近在看<TCP/IP具体解释>系列书总结出来的,之后会陆续把其它协议部分分享出来. 我尽量以简单易读.易懂的方式呈现出来,可是,因为文笔和水平有限.有些地方或许存在描写叙述上的不足或 ...

  8. 构建基于Javascript的移动web CMS——Hello,World

    在一篇构建基于Javascript的移动web CMS入门--简单介绍中简单的介绍了关于墨颀CMS的一些原理,其极框架组成.于是開始接着应该说明一下这个CMS是怎样一步步搭建起来. RequireJS ...

  9. Andriod三步学会安卓自己定义视图及其属性

    第一步:自己定义属性 第二步:自己定义控件解析属性 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcm5adW9adW8=/font/5a6L5L2T/fo ...

  10. pandas-数据分析

    pandas是一个强大的python数据分析的工具包 pandas是基于numpy构建的 pandas的主要功能: 具备对其功能的数据结构DataFrame.Series 集成世间序列功能 提供丰富的 ...