link:http://www.usaco.org/index.php?page=dec17results

Problem A(Bronze)

这是一道非常简单的判断重叠面积的题目,但第一次提交仍会出错,实不应该

判断的关键在于矩形A的上界要大于B的下界,且A的下界要小于B的上界,则包含了相重叠的所有情况

同时,在数据范围较小时,也可使用染色法

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. typedef long long ll;
  5.  
  6. int xx[],xy[],yx[],yy[];
  7.  
  8. ll cal(int n,int m)
  9. {
  10. ll ret=(xy[n]-xx[n])*(yy[n]-yx[n]);
  11. if(xx[m]<=xy[n] && xy[m]>=xx[n] && yx[m]<=yy[n] && yy[m]>=yx[n]) //关键判断句
  12. {
  13. ll t1=min(xy[n],xy[m])-max(xx[n],xx[m]);
  14. ll t2=min(yy[n],yy[m])-max(yx[n],yx[m]);
  15. ret-=t1*t2;
  16. }
  17. return ret;
  18. }
  19.  
  20. int main()
  21. {
  22. for(int i=;i<;i++)
  23. cin >> xx[i] >> yx[i] >> xy[i] >> yy[i];
  24.  
  25. ll res=cal(,);res+=cal(,);
  26. cout << res;
  27.  
  28. return ;
  29. }

Problem A

Problem B、C(Bronze)

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. struct milk
  6. {
  7. int day,num,change;
  8. }dat[];
  9. int n,res[],cnt=;
  10.  
  11. bool cmp(milk a,milk b)
  12. {
  13. return a.day<b.day;
  14. }
  15.  
  16. int main()
  17. {
  18. cin >> n;
  19. for(int i=;i<=n;i++)
  20. {
  21. string s;
  22. cin >> dat[i].day >> s >> dat[i].change;
  23. if(s=="Bessie") dat[i].num=;
  24. else if(s=="Elsie") dat[i].num=;
  25. else dat[i].num=;
  26. }
  27. sort(dat+,dat+n+,cmp);
  28.  
  29. int cur=;
  30. res[]=res[]=res[]=;
  31. for(int i=;i<=n;i++)
  32. {
  33. res[dat[i].num]+=dat[i].change;
  34. int t1=max(res[],max(res[],res[])),t2=;
  35. for(int j=;j<=;j++) if(res[j]==t1) t2+=(<<(j-));
  36.  
  37. if(t2!=cur) cur=t2,cnt++;
  38. }
  39. cout << cnt;
  40. return ;
  41. }

Problem B

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. int n,a[],rev[],ini[],res[];
  5.  
  6. int main()
  7. {
  8. cin >> n;
  9. for(int i=;i<=n;i++) cin >> a[i];
  10. for(int i=;i<=n;i++) cin >> ini[i];
  11. for(int i=;i<=n;i++) rev[a[i]]=i;
  12.  
  13. for(int i=;i<=n;i++)
  14. {
  15. int t=i;
  16. for(int j=;j<=;j++) t=rev[t];
  17. res[t]=ini[i];
  18. }
  19.  
  20. for(int i=;i<=n;i++) cout << res[i] << endl;
  21. return ;
  22. }

Problem C

Problem A(Silver)

只要每次预处理最小值和前缀和即可

Tip:用double存储两int相除时一定要强制类型转换

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. int n,a[],mmin[];
  5. double ave[],mmax=;
  6.  
  7. int main()
  8. {
  9. cin >> n;
  10. for(int i=;i<=n;i++) cin >> a[i];
  11. mmin[n]=a[n];mmax=;int sum=a[n];
  12. for(int i=n-;i>=;i--)
  13. {
  14. mmin[i]=min(mmin[i+],a[i]);
  15. sum+=a[i];ave[i]=double(sum-mmin[i])/(n-i);
  16. //一定要强制转换为double
  17. mmax=max(mmax,ave[i]);
  18. }
  19.  
  20. for(int i=;i<=n-;i++) if(ave[i]==mmax) cout << i- << endl;
  21.  
  22. return ;
  23. }

Problem A

 Problem B(Silver)

这是一道让我收获很大的题

题面:有n个起始为g的数,在m天里每天都会对其中一个数进行调整(加或减),而你要维护一个最大值列表,包括所有为当前最大值的数的编号。问此列表要改变的次数。

n<=1e9,m<=1e6

从数据范围可以看出,我们无法也不需要对每一个数进行维护,仅需对可能发生改变的1e6个数维护即可,那么为了建立每一个编号及其值之间的关系,可以用map来进行维护

那么接下来的重点就在于如何维护这些已经改变过的数的最大值,以及当前最大值的个数

一开始我并未使用数据结构,直接对最大值,次大值进行维护,但实际上当上一步的最大值进行减法时,需要再进行一次排序,因此不可行

实际上map中也是有自带的排序的,默认map<int,int,less<int> >,从而我们也可以使用greater<int>来使其降序排列,并用map.begin()来调取其最大的键所对应的值

同时,map本身内部的数据结构又是pair性质的,因此有了iterator:map.begin()后,可以使用map.begin()->first调取键,用map.begin()->second调取值

这样,我们就可以再用一个map来表示当前每种值所对应的数的个数

Tip:1、map.erase()操作不用输入iterator,只要输入键的编号即可

2、map本身和set一样,均自动排序,可用begin()调用最值

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. struct milk
  6. {
  7. int day,num,change;
  8. }dat[];
  9.  
  10. int n,g;
  11. map<int,int> mp;
  12. map<int,int,greater<int> > cnt;
  13.  
  14. bool cmp(milk p,milk q)
  15. {
  16. return p.day<q.day;
  17. }
  18.  
  19. int main()
  20. {
  21. cin >> n >> g;
  22. for(int i=;i<=n;i++)
  23. {
  24. cin >> dat[i].day >> dat[i].num >> dat[i].change;
  25. if(!mp.count(dat[i].num)) mp[dat[i].num]=g;
  26. }
  27.  
  28. sort(dat+,dat+n+,cmp);
  29.  
  30. int res=;cnt[g]=n;
  31. for(int i=;i<=n;i++)
  32. {
  33. int last=mp[dat[i].num];mp[dat[i].num]+=dat[i].change;
  34. int lmax=cnt.begin()->first,lcnt=cnt.begin()->second; //调用最大值的键值对
  35.  
  36. if(cnt[last]==) cnt.erase(last); //erase操作
  37. else cnt[last]--;
  38. cnt[mp[dat[i].num]]++;
  39.  
  40. if(last==lmax)
  41. { //如果更改后最大值的编号不变且均只有一个最大值,则不处理
  42. if(mp[dat[i].num]==cnt.begin()->first && cnt[mp[dat[i].num]]== && lcnt==) continue;
  43. res++;
  44. }
  45. else if(mp[dat[i].num]>=lmax) res++;
  46. }
  47. cout << res;
  48.  
  49. return ;
  50. }

Problem B

Problem C(Silver)

题意:经过分析后,其实就是求所有在环中的点的总数

我看到此题后直接无脑用了tarjan,通过求强联通分量找到所有的环

但实际上,由于此题的特殊性:每个数仅有一个儿子,因此可以使用类似于topo sort的方法来剪去所有不成环的点

原理是当一个点的入度全部为不在环上的点组成时,则其也一定不在环上

1、首先将所有入度为0的点加入队列

2、每次删去队列中的一个点并将其所有出边删除

3、将操作后入度为0的点再加入队列

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. const int MAXN=;
  5. int n,dfn[MAXN],low[MAXN],dat[MAXN],time_point=,res=;
  6. bool vis[MAXN],instack[MAXN];
  7.  
  8. stack<int> s;
  9.  
  10. void tarjan(int node)
  11. {
  12. time_point++;
  13. dfn[node]=low[node]=time_point;
  14. vis[node]=true;
  15. s.push(node);
  16. instack[node]=true;
  17.  
  18. if(!vis[dat[node]])
  19. {
  20. tarjan(dat[node]);
  21. low[node]=min(low[node],low[dat[node]]);
  22. }
  23. else if(instack[dat[node]]) low[node]=min(low[node],low[dat[node]]);
  24.  
  25. if(low[node]==dfn[node])
  26. {
  27. int temp,sum=;
  28. do
  29. {
  30. temp=s.top();
  31. res++;sum++;
  32. s.pop();
  33. instack[temp]=false;
  34. }
  35. while(temp!=node);
  36. if(sum== && dat[temp]!=temp) res--;
  37. }
  38. }
  39.  
  40. int main()
  41. {
  42. cin >> n;
  43. for(int i=;i<=n;i++) cin >> dat[i];
  44.  
  45. for(int i=;i<=n;i++)
  46. if(!vis[i]) tarjan(i);
  47.  
  48. cout << res;
  49. return ;
  50. }

Solution A

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. int in[],n;
  5. bool res[];
  6. vector<int> a[];
  7.  
  8. int main()
  9. {
  10. memset(res,true,sizeof(res));
  11. int n;cin >> n;
  12. for(int i=;i<=n;i++)
  13. {
  14. int x;cin >> x;
  15. in[x]++;
  16. a[i].push_back(x);
  17. }
  18.  
  19. queue<int> q;
  20. for(int i=;i<=n;i++)
  21. if(!in[i]) q.push(i),res[i]=false;
  22.  
  23. while(!q.empty())
  24. {
  25. int x;x=q.front();q.pop();
  26. for(int i=;i<a[x].size();i++)
  27. {
  28. in[a[x][i]]--;
  29. if(!in[a[x][i]]) q.push(a[x][i]),res[a[x][i]]=false;
  30. }
  31. }
  32.  
  33. int sum=;
  34. for(int i=;i<=n;i++) sum+=res[i];
  35. cout << sum;
  36.  
  37. return ;
  38. }

Solution B

因此可以发现拓扑排序和求环算法中的一些联系

[USACO] 2017 DEC Bronze&Silver的更多相关文章

  1. [USACO 2017 Dec Gold] Tutorial

    Link: USACO 2017 Dec Gold 传送门 A: 为了保证复杂度明显是从终结点往回退 结果一开始全在想优化建边$dfs$……其实可以不用建边直接$multiset$找可行边跑$bfs$ ...

  2. NC24083 [USACO 2017 Dec P]Greedy Gift Takers

    NC24083 [USACO 2017 Dec P]Greedy Gift Takers 题目 题目描述 Farmer John's nemesis, Farmer Nhoj, has N cows ...

  3. USACO翻译:USACO 2013 DEC Silver三题

    USACO 2013 DEC SILVER 一.题目概览 中文题目名称 挤奶调度 农场航线 贝西洗牌 英文题目名称 msched vacation shuffle 可执行文件名 msched vaca ...

  4. USACO翻译:USACO 2014 DEC Silver三题

    USACO 2014 DEC SILVER 一.题目概览 中文题目名称 回程 马拉松 奶牛慢跑 英文题目名称 piggyback marathon cowjog 可执行文件名 piggyback ma ...

  5. NC24866 [USACO 2009 Dec S]Music Notes

    NC24866 [USACO 2009 Dec S]Music Notes 题目 题目描述 FJ is going to teach his cows how to play a song. The ...

  6. 【BZOJ】【1717】【USACO 2006 Dec】Milk Patterns产奶的模式

    后缀数组 o(︶︿︶)o 唉傻逼了一下,忘了把后缀数组的字典范围改回20001,直接21交了上去,白白RE了两发……sigh 既然要找出现了K次的子串嘛,那当然要用后缀数组了>_>(因为我 ...

  7. USACO 2017 February Platinum

    第二次参加USACO 本来打算2016-2017全勤的 January的好像忘记打了 听群里有人讨论才想起来铂金组三题很有意思,都是两个排列的交叉对问题 我最后得分889/1000(真的菜) T1.W ...

  8. 【BZOJ】【1986】【USACO 2004 Dec】/【POJ】【2373】划区灌溉

    DP/单调队列优化 首先不考虑奶牛的喜欢区间,dp方程当然是比较显然的:$ f[i]=min(f[k])+1,i-2*b \leq k \leq i-2*a $  当然这里的$i$和$k$都是偶数啦~ ...

  9. Usaco 2010 Dec Gold Exercise(奶牛健美操)

    /*codevs 3279 二分+dfs贪心检验 堆版本 re一个 爆栈了*/ #include<cstdio> #include<queue> #include<cst ...

随机推荐

  1. MyBatis 框架系列之基础初识

    MyBatis 框架系列之基础初识 1.什么是 MyBatis MyBatis 本是 apache 的一个开源项目 iBatis,后改名为 MyBatis,它 是一个优秀的持久层框架,对 jdbc 的 ...

  2. Vue 键盘事件

    Vue2键盘事件:keydown/keyup... 1.使用 <!DOCTYPE html> <html> <head> <title></tit ...

  3. bzoj 3035 二分答案+二分图最大匹配

    大原来做的一道题,偷懒直接粘的原来的程序 http://www.cnblogs.com/BLADEVIL/p/3433520.html /******************************* ...

  4. (Git 钩子)自定义你的工作流 和引用日志

    Git 钩子是在 Git 仓库中特定事件发生时自动运行的脚本.它可以让你自定义 Git 内部的行为,在开发周期中的关键点触发自定义的行为. Git 钩子最常见的使用场景包括推行提交规范,根据仓库状态改 ...

  5. ssh日常优化使用

    config文件的使用 ssh命令默认会加载 ~/.ssh/config 文件作为配置文件,如果没有则采用默认配置.如果我们想要对ssh进行定制,那么就可以使用如下方法 [root@linux-nod ...

  6. 分布式队列Celery

    Celery是什么? Celery 是一个由 Python 编写的简单.灵活.可靠的用来处理大量信息的分布式系统,它同时提供操作和维护分布式系统所需的工具. Celery 专注于实时任务处理,支持任务 ...

  7. 集合类---Map

    Map常用的子类: 一.HashMap详解  1.特点 1)线程不安全.如果想要得到线程安全的HashMap,可以使用Collections的静态方法:Map map = Collections.sy ...

  8. HDU 6183 Color it 线段树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6183 题意: 有四种操作: 0:清除所有点 1 x y c : 给点(x, y)添加一种颜色c(颜色不 ...

  9. pxe+kickstart自动化安装

    什么是PXE? PXE(Pre-boot Execution Environment,预启动执行环境)是Intel公司开发的最新技术,工作于Client/Server模式.PXE是一种远程引导方式,要 ...

  10. Linux磁盘的性能详细测试办法

    # 测试写入20Gb文件sync && time -p bash -c "(dd if=/dev/zero of=test.dd  bs=1000K count=20000; ...