[USACO] 2017 DEC Bronze&Silver
link:http://www.usaco.org/index.php?page=dec17results
Problem A(Bronze)
这是一道非常简单的判断重叠面积的题目,但第一次提交仍会出错,实不应该
判断的关键在于矩形A的上界要大于B的下界,且A的下界要小于B的上界,则包含了相重叠的所有情况
同时,在数据范围较小时,也可使用染色法
#include <bits/stdc++.h> using namespace std;
typedef long long ll; int xx[],xy[],yx[],yy[]; ll cal(int n,int m)
{
ll ret=(xy[n]-xx[n])*(yy[n]-yx[n]);
if(xx[m]<=xy[n] && xy[m]>=xx[n] && yx[m]<=yy[n] && yy[m]>=yx[n]) //关键判断句
{
ll t1=min(xy[n],xy[m])-max(xx[n],xx[m]);
ll t2=min(yy[n],yy[m])-max(yx[n],yx[m]);
ret-=t1*t2;
}
return ret;
} int main()
{
for(int i=;i<;i++)
cin >> xx[i] >> yx[i] >> xy[i] >> yy[i]; ll res=cal(,);res+=cal(,);
cout << res; return ;
}
Problem A
Problem B、C(Bronze)
#include <bits/stdc++.h> using namespace std; struct milk
{
int day,num,change;
}dat[];
int n,res[],cnt=; bool cmp(milk a,milk b)
{
return a.day<b.day;
} int main()
{
cin >> n;
for(int i=;i<=n;i++)
{
string s;
cin >> dat[i].day >> s >> dat[i].change;
if(s=="Bessie") dat[i].num=;
else if(s=="Elsie") dat[i].num=;
else dat[i].num=;
}
sort(dat+,dat+n+,cmp); int cur=;
res[]=res[]=res[]=;
for(int i=;i<=n;i++)
{
res[dat[i].num]+=dat[i].change;
int t1=max(res[],max(res[],res[])),t2=;
for(int j=;j<=;j++) if(res[j]==t1) t2+=(<<(j-)); if(t2!=cur) cur=t2,cnt++;
}
cout << cnt;
return ;
}
Problem B
#include <bits/stdc++.h> using namespace std;
int n,a[],rev[],ini[],res[]; int main()
{
cin >> n;
for(int i=;i<=n;i++) cin >> a[i];
for(int i=;i<=n;i++) cin >> ini[i];
for(int i=;i<=n;i++) rev[a[i]]=i; for(int i=;i<=n;i++)
{
int t=i;
for(int j=;j<=;j++) t=rev[t];
res[t]=ini[i];
} for(int i=;i<=n;i++) cout << res[i] << endl;
return ;
}
Problem C
Problem A(Silver)
只要每次预处理最小值和前缀和即可
Tip:用double存储两int相除时一定要强制类型转换
#include <bits/stdc++.h> using namespace std;
int n,a[],mmin[];
double ave[],mmax=; int main()
{
cin >> n;
for(int i=;i<=n;i++) cin >> a[i];
mmin[n]=a[n];mmax=;int sum=a[n];
for(int i=n-;i>=;i--)
{
mmin[i]=min(mmin[i+],a[i]);
sum+=a[i];ave[i]=double(sum-mmin[i])/(n-i);
//一定要强制转换为double
mmax=max(mmax,ave[i]);
} for(int i=;i<=n-;i++) if(ave[i]==mmax) cout << i- << endl; return ;
}
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()调用最值
#include <bits/stdc++.h> using namespace std; struct milk
{
int day,num,change;
}dat[]; int n,g;
map<int,int> mp;
map<int,int,greater<int> > cnt; bool cmp(milk p,milk q)
{
return p.day<q.day;
} int main()
{
cin >> n >> g;
for(int i=;i<=n;i++)
{
cin >> dat[i].day >> dat[i].num >> dat[i].change;
if(!mp.count(dat[i].num)) mp[dat[i].num]=g;
} sort(dat+,dat+n+,cmp); int res=;cnt[g]=n;
for(int i=;i<=n;i++)
{
int last=mp[dat[i].num];mp[dat[i].num]+=dat[i].change;
int lmax=cnt.begin()->first,lcnt=cnt.begin()->second; //调用最大值的键值对 if(cnt[last]==) cnt.erase(last); //erase操作
else cnt[last]--;
cnt[mp[dat[i].num]]++; if(last==lmax)
{ //如果更改后最大值的编号不变且均只有一个最大值,则不处理
if(mp[dat[i].num]==cnt.begin()->first && cnt[mp[dat[i].num]]== && lcnt==) continue;
res++;
}
else if(mp[dat[i].num]>=lmax) res++;
}
cout << res; return ;
}
Problem B
Problem C(Silver)
题意:经过分析后,其实就是求所有在环中的点的总数
我看到此题后直接无脑用了tarjan,通过求强联通分量找到所有的环
但实际上,由于此题的特殊性:每个数仅有一个儿子,因此可以使用类似于topo sort的方法来剪去所有不成环的点
原理是当一个点的入度全部为不在环上的点组成时,则其也一定不在环上
1、首先将所有入度为0的点加入队列
2、每次删去队列中的一个点并将其所有出边删除
3、将操作后入度为0的点再加入队列
#include <bits/stdc++.h> using namespace std;
const int MAXN=;
int n,dfn[MAXN],low[MAXN],dat[MAXN],time_point=,res=;
bool vis[MAXN],instack[MAXN]; stack<int> s; void tarjan(int node)
{
time_point++;
dfn[node]=low[node]=time_point;
vis[node]=true;
s.push(node);
instack[node]=true; if(!vis[dat[node]])
{
tarjan(dat[node]);
low[node]=min(low[node],low[dat[node]]);
}
else if(instack[dat[node]]) low[node]=min(low[node],low[dat[node]]); if(low[node]==dfn[node])
{
int temp,sum=;
do
{
temp=s.top();
res++;sum++;
s.pop();
instack[temp]=false;
}
while(temp!=node);
if(sum== && dat[temp]!=temp) res--;
}
} int main()
{
cin >> n;
for(int i=;i<=n;i++) cin >> dat[i]; for(int i=;i<=n;i++)
if(!vis[i]) tarjan(i); cout << res;
return ;
}
Solution A
#include <bits/stdc++.h> using namespace std;
int in[],n;
bool res[];
vector<int> a[]; int main()
{
memset(res,true,sizeof(res));
int n;cin >> n;
for(int i=;i<=n;i++)
{
int x;cin >> x;
in[x]++;
a[i].push_back(x);
} queue<int> q;
for(int i=;i<=n;i++)
if(!in[i]) q.push(i),res[i]=false; while(!q.empty())
{
int x;x=q.front();q.pop();
for(int i=;i<a[x].size();i++)
{
in[a[x][i]]--;
if(!in[a[x][i]]) q.push(a[x][i]),res[a[x][i]]=false;
}
} int sum=;
for(int i=;i<=n;i++) sum+=res[i];
cout << sum; return ;
}
Solution B
因此可以发现拓扑排序和求环算法中的一些联系
[USACO] 2017 DEC Bronze&Silver的更多相关文章
- [USACO 2017 Dec Gold] Tutorial
Link: USACO 2017 Dec Gold 传送门 A: 为了保证复杂度明显是从终结点往回退 结果一开始全在想优化建边$dfs$……其实可以不用建边直接$multiset$找可行边跑$bfs$ ...
- 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 ...
- USACO翻译:USACO 2013 DEC Silver三题
USACO 2013 DEC SILVER 一.题目概览 中文题目名称 挤奶调度 农场航线 贝西洗牌 英文题目名称 msched vacation shuffle 可执行文件名 msched vaca ...
- USACO翻译:USACO 2014 DEC Silver三题
USACO 2014 DEC SILVER 一.题目概览 中文题目名称 回程 马拉松 奶牛慢跑 英文题目名称 piggyback marathon cowjog 可执行文件名 piggyback ma ...
- 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 ...
- 【BZOJ】【1717】【USACO 2006 Dec】Milk Patterns产奶的模式
后缀数组 o(︶︿︶)o 唉傻逼了一下,忘了把后缀数组的字典范围改回20001,直接21交了上去,白白RE了两发……sigh 既然要找出现了K次的子串嘛,那当然要用后缀数组了>_>(因为我 ...
- USACO 2017 February Platinum
第二次参加USACO 本来打算2016-2017全勤的 January的好像忘记打了 听群里有人讨论才想起来铂金组三题很有意思,都是两个排列的交叉对问题 我最后得分889/1000(真的菜) T1.W ...
- 【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$都是偶数啦~ ...
- Usaco 2010 Dec Gold Exercise(奶牛健美操)
/*codevs 3279 二分+dfs贪心检验 堆版本 re一个 爆栈了*/ #include<cstdio> #include<queue> #include<cst ...
随机推荐
- python学习笔记(五)数值类型和类型转换
Python中的数值类型有: 整型,如2,520 浮点型,如3.14159,1.5e10 布尔类型 True和False e记法: e记法即对应数学中的科学记数法 >>> 1.5e1 ...
- python作业三级菜单day1(第一周)
一.作业需求: 1. 运行程序输出第一级菜单 2. 选择一级菜单某项,输出二级菜单,同理输出三级菜单 3. 菜单数据保存在文件中 4. 让用户选择是否要退出 5. 有返回上一级菜单的功能 二三级菜单文 ...
- 项目记录 -- zfs get all [volume] python实现的数据构造
zfs get all [volume]命令实现中构造数据结构 一.zfs get all [volume]命令源代码C实现中用到的数据结构有zprop_get_cbdata 和 callback_d ...
- hdfs文件上传机制与namenode元数据管理机制
1.hdfs文件上传机制 文件上传过程: 1.客户端想NameNode申请上传文件, 2.NameNode返回此次上传的分配DataNode情况给客户端 3.客户端开始依向dataName上传对应 ...
- 【shell】shell中各种括号的作用()、(())、[]、[[]]、{}
一.小括号,圆括号() 1.单小括号 () ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有 ...
- linux 3389连接工具Rdesktop
简单使用 工作机换成战斗机了,改用ubuntu,原来的windows7上东西笔记多,还不想重装.用rdesktop来远程连接windows: sudo apt-get install rdesktop ...
- C++学习之路(八):关于C++提供的强制类型转换
C语言中提供了旧式的强制类型转换方法.比如: int a =1; char *p = (char *)&a; 上述将a的地址单元强制转换为char类型的指针.这里暂且不说上述转换结果是否合理 ...
- 排名函数row_number() over(order by)用法
1. 定义 简单的说row_number()从1开始,为每一条分组记录返回一个数字,这里的ROW_NUMBER() OVER (ORDER BY [列名]DESC) 是先把[列名]降序排列,再为降序以 ...
- SVN服务的配置与管理
引言 没当服务器重启,SVN服务都会停止,每次都得重启一下服务,为了解决这样的问题.有了下文. 一.配置自启动服务 sc create SVNService binpath="E:\svn\ ...
- javascript方法--apply()
今天琢磨了一下apply,以前对这个方法觉得比较懵,今天一琢磨确实觉得挺好玩的. 一开始把MDN的apply文档看了一遍,感觉不是很理解,而且有一些东西也是知道但是比较模糊,所以还是一步一步来,不懂查 ...