目录:
T1:The Great Revegetation
T2:Measuring Traffic
T3:MooBuzz
T4:Milk Visits
老USACO了……
正题:
T1:The Great Revegetation
题目描述
长时间的干旱使得Farmer John的N块草地上牧草匮乏。随着雨季即将到来,现在应当是重新种植的时候了。
在Farmer John的储物棚里有四个桶,每个桶里装着一种不同的草种。他想要在每块草地上播种其中一种草。作为一名奶农,Farmer John想要确保他的每头奶牛都能得到丰富的食谱。他的M头奶牛每一头都有两块喜爱的草地,他想要确保这两块草地种植不同种类的草,从而每头奶牛都可以有两种草可供选择。Farmer John知道没有一块草地受到多于3头奶牛的喜爱。
请帮助Farmer John选择每块草地所种的草的种类,使得所有奶牛的营养需求都得到满足。
输入
输入的第一行包含N(2≤N≤100)和M(1≤M≤150)。以下M行,每行包含两个范围为1…N的整数,为Farmer John的一头奶牛喜欢的两块草地。
输出
输出一个N位数,每一位均为1…4之一,表示每一块草地上所种的草的种类。第一位对应草地1的草的种类,第二位对应草地2,以此类推。如果有多种可行的解,只需输出所有解中最小的N位数。
样例输入
5 6
4 1
4 2
4 3
2 5
1 2
1 5
样例输出
12133
分析:
暴力枚举
然后输出当前情况
用标记结束循环
CODE:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
freopen("revegetate.in","r",stdin);
freopen("revegetate.out","w",stdout);
int n,m;
int a[151],b[151],g[101];
cin>>n>>m;
for(int i=0;i<m;i++) {
cin>>a[i]>>b[i];
if(a[i]>b[i]) swap(a[i],b[i]); //大小区分,方便后面判断
}
for(int i=1;i<=n;i++){
int k;
for(k=1;k<=4;k++){ //枚举
bool f=true;
for(int j=0;j<m;j++){
if(b[j]==i&&g[a[j]]==k){ //编号相同,数值相同
f=false;
}
}
if(f) break; //停止
}
g[i]=k; //存入
cout<<k;
}
return 0;
}
T2:Measuring Traffic
题目描述
Farmer John的农场边上的高速公路最近出现了引人注目的流量上升,或者至少Farmer John看起来是这样的。为了证实这件事,他打算用一组传感器测量公路上的车流量,每个传感器被用来测量一小段路面上的车流量的数值。
不幸的是,某一天经过牛棚的时候,Farmer John被绊倒了,装有传感器的盒子掉进了一个巨大的奶缸,之后它们就不能正常工作了。比起之前可以产生一个精确的车流量读数,现在每个传感器只能输出一个可能结果的范围。例如,一个传感器可能会给出范围[7,13],表示在这段路面上的车流量不小于7,并且不大于13。
高速公路经过农场的这一段长N英里,车辆仅从一个方向通过公路,从第1英里驶向第N英里。Farmer John想要安装N个传感器——每一个监测高速公路上1英里长的路段。在其中某些路段上,有能够使得车辆进入高速公路的上匝道;在所有这样的路段上,Farmer John会将传感器装在上匝道上,测量流入的(近似)车流量。在某些路段上有能够使得车辆离开高速公路的下匝道;在所有这样的路段上,Farmer John会将传感器装在下匝道上。每一个路段包含至多一个匝道。如果在公路的一个路段上没有上匝道或下匝道,Farmer John就将传感器装在高速公路的主路上。
给定Farmer John的N个传感器的读数,请求出在高速公路第1英里之前和第N英里之后车流量的最为准确的可能范围。这些范围应当与所有N个传感器的读数相一致。
输入
输入的第一行包含N(1≤N≤100)。余下N行每行按从第1英里至第N英里的顺序描述一段1英里长的路段。每行包含一个字符串,为"on"(如果这段路上有一个上匝道),“off”(如果这段路上有一个下匝道),或者是"none"(如果这段路上没有匝道),然后是两个范围为0…1000的整数,表示这段路上的传感器的读数所给出的下界、上界。如果这段路上包含匝道,传感器读数来自于匝道,否则来自于主路。至少一个高速公路路段的描述会是"none"。
输出
输出的第一行包含两个整数,为第1英里之前的车流量的最准确的可能范围。第二行包含两个整数,为第N英里之后的车流量的最准确的可能范围。输入保证存在符合要求的解。
样例输入
4
on 1 1
none 10 14
none 11 15
off 2 3
样例输出
10 13
8 12
分析:
做两遍
分三种情况:
① none 用来取范围
② on 意为进车 也就是做加法
③ off 意为放车 也就是做减法
CODE:
#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
using namespace std;
int m,n;
struct node{
string f;
int x,y;
}a[1001000];
int main(){
freopen("traffic.in","r",stdin);
freopen("traffic.out","w",stdout);
int l=0,r=1000100;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].f>>a[i].x>>a[i].y;
if(a[i].f=="none"){ //取范围
l=max(l,a[i].x);
r=min(r,a[i].y);
}
if(a[i].f=="on"){ //加法
l+=a[i].x;
r+=a[i].y;
}
if(a[i].f=="off"){ //减法
l-=a[i].y;
r-=a[i].x;
}
l=max(l,0);
}
int l2=0,r2=1000010;
for(int i=n;i>=1;i--){ //同理,反着来做第二遍
if(a[i].f=="none"){
l2=max(l2,a[i].x);
r2=min(r2,a[i].y);
}
if(a[i].f=="on"){
l2-=a[i].y;
r2-=a[i].x;
}
if(a[i].f=="off"){
l2+=a[i].x;
r2+=a[i].y;
}
l2=max(l2,0);
}
cout<<l2<<' '<<r2<<endl<<l<<' '<<r;
return 0;
}
T3:MooBuzz
题目描述
Farmer John 的奶牛们最近成为了一个简单的数字游戏“FizzBuzz”的狂热玩家。这个游戏的规则很简单:奶牛们站成一圈,依次从一开始报数,每头奶牛在轮到她的时候报一个数。如果一头奶牛将要报的数字是 3 的倍数,她应当报“Fizz”来代替这个数。如果一头奶牛将要报的数字是 5 的倍数,她应当报“Buzz”来代替这个数。如果一头奶牛将要报的数字是 15 的倍数,她应当报“FizzBuzz”来代替这个数。于是这个游戏的开始部分的记录为:
1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, 11, Fizz, 13, 14, FizzBuzz, 16
由于词汇的匮乏,奶牛们玩的 FizzBuzz 中用“Moo”代替了 Fizz、Buzz、FizzBuzz。于是奶牛版的游戏的开始部分的记录为:
1, 2, Moo, 4, Moo, Moo, 7, 8, Moo, Moo, 11, Moo, 13, 14, Moo, 16
给定 N(1≤N≤10^9),请求出这个游戏中第 N 个被报的数。
输入
输入包含一个整数 N。
输出
输出游戏中被报出的第 N 个数。
样例输入
4
样例输出
7
分析:
很明显是周期问题
15为一个周期 用一个数组存下15内不是“Moo”的数
累加周期位数
CODE:
#include<cmath>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long LL;
int a[9]={14,1,2,4,7,8,11,13}; //15内非Moo的数
int n,x,ans;
int main(){
freopen("moobuzz.in","r",stdin);
freopen("moobuzz.out","w",stdout);
scanf("%d",&n);
x=n/8;
ans=x*15;
if(n%8!=0) ans+=a[n%8]; //累加周期位数
else ans--; //直接ans--即可
printf("%d",ans);
return 0;
}
T4:Milk Visits
题目描述
Farmer John 计划建造 N(1≤N≤10^5)个农场,用 N−1 条道路连接,构成一棵树(也就是说,所有农场之间都互相可以到达,并且没有环)。每个农场有一头奶牛,品种为更赛牛或荷斯坦牛之一。
Farmer John 的 M 个朋友(1≤M≤10^5)经常前来拜访他。在朋友 i 拜访之时,Farmer John 会与他的朋友沿着从农场 Ai 到农场 Bi 之间的唯一路径行走(可能有 Ai=Bi)。除此之外,他们还可以品尝他们经过的路径上任意一头奶牛的牛奶。由于 Farmer John 的朋友们大多数也是农场主,他们对牛奶有着极强的偏好。他的有些朋友只喝更赛牛的牛奶,其余的只喝荷斯坦牛的牛奶。任何 Farmer John 的朋友只有在他们访问时能喝到他们偏好的牛奶才会高兴。
请求出每个朋友在拜访过后是否会高兴。
输入
输入的第一行包含两个整数 N 和 M。
第二行包含一个长为 N 的字符串。如果第 i 个农场中的奶牛是更赛牛,则字符串中第 i 个字符为 ‘G’,如果第 i 个农场中的奶牛是荷斯坦牛则为 ‘H’。
接下来下 N−1 行,每行包含两个不同的整数 X 和 Y(1≤X,Y≤N),表示农场 X 与 Y 之间有一条道路。
接下来下 M 行,每行包含整数 Ai,Bi,以及一个字符 Ci。Ai 和 Bi 表示朋友 i 拜访时行走的路径的端点,Ci 是 ‘G’ 或 ‘H’ 之一,表示第 i 个朋友喜欢更赛牛的牛奶或是荷斯坦牛的牛奶。
输出
输出一个长为 M 的二进制字符串。如果第 i 个朋友会感到高兴,则字符串的第 i 个字符为 ‘1’,否则为 ‘0’。
样例输入
5 5
HHGHG
1 2
2 3
2 4
1 5
1 4 H
1 4 G
1 3 G
1 3 H
5 5 H
样例输出
10110
分析:
并查集模板 好像要用快读
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
inline int read(){ //快读
int s=0,f=1;char c=getchar();
while(c<'0'||c>'9'){
if(c=='H'||c=='G')return c;
if(c=='-')f=-1;c=getchar();
}
while(c>='0'&&c<='9'){
s=(s<<1)+(s<<3)+(c^48);c=getchar();
}
return f*s;
}
int n,m,b[100001];
char c[100001];
int find(int x){
if(b[x]!=x){
b[x]=find(b[x]); //也就是getfather函数
}
return b[x];
}
int main(){
freopen("milkvisits.in","r",stdin);
freopen("milkvisits.out","w",stdout);
n=read(),m=read();
scanf("%s",c+1);
for(int i=1;i<=n;i++)b[i]=i;
for(int i=1;i<n;i++){
int x=read(),y=read();
if(c[x]==c[y])b[find(x)]=find(y); //并查集模板
}
for(int i=1;i<=m;i++){
int x=read(),y=read(),z=read();
printf("%d",find(x)!=find(y)||c[x]==z); //可直接输出表达式运算结果真假
}
return 0;
}