题面
A. Fence Planning
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Farmer John’s N cows, conveniently numbered 1…N (2≤N≤105), have a complex social structure revolving around “moo networks” — smaller groups of cows that communicate within their group but not with other groups. Each cow is situated at a distinct (x,y) location on the 2D map of the farm, and we know that M pairs of cows (1≤M<105) moo at each-other. Two cows that moo at each-other belong to the same moo network.
In an effort to update his farm, Farmer John wants to build a rectangular fence, with its edges parallel to the x and y axes. Farmer John wants to make sure that at least one moo network is completely enclosed by the fence (cows on the boundary of the rectangle count as being enclosed). Please help Farmer John determine the smallest possible perimeter of a fence that satisfies this requirement. It is possible for this fence to have zero width or zero height.
Input
The first line of input contains N and M. The next N lines each contain the x and y coordinates of a cow (nonnegative integers of size at most 108). The next M lines each contain two integers a and b describing a moo connection between cows a and b. Every cow has at least one moo connection, and no connection is repeated in the input.
Output
Please print the smallest perimeter of a fence satisfying Farmer John’s requirements.
Example
inputCopy
7 5
0 5
10 5
5 0
5 10
6 7
8 6
8 4
1 2
2 3
3 4
5 6
7 6
outputCopy
10
分析
dfs遍历每个连通块,并得到最小和最大的x坐标,y坐标
求该连通块的最小矩形周长
代码
#include<iostream>
using namespace std;
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<string>
#include<cmath>
#include<vector>
typedef long long ll;
const int INF=1e9;
const int MAX_N=1e5+5;
int n,m;
int ans=INF;
int X[MAX_N],Y[MAX_N],F[MAX_N];
int x,xx,y,yy;
vector<int> g[MAX_N];
void dfs(int i){
if(F[i]) return ;
F[i]=1;
x=min(x,X[i]),y=min(y,Y[i]);
xx=max(xx,X[i]),yy=max(yy,Y[i]);
for(int j=0;j<g[i].size();j++){
int k=g[i][j];
if(!F[k]) dfs(k);
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d",&X[i],&Y[i]);
}
for(int i=1;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
g[a].push_back(b);
g[b].push_back(a);
}
for(int i=1;i<=n;i++){
x=y=INF,xx=yy=-INF;
if(!F[i]) dfs(i);
ans=min(ans,2*(xx-x+yy-y));
}
printf("%d\n",ans);
return 0;
}
题面
F. Milk Factory
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
The milk business is booming! Farmer John’s milk processing factory consists of N processing stations, conveniently numbered 1…N (1≤N≤100), and N−1 walkways, each connecting some pair of stations. (Walkways are expensive, so Farmer John has elected to use the minimum number of walkways so that one can eventually reach any station starting from any other station). To try and improve efficiency, Farmer John installs a conveyor belt in each of its walkways. Unfortunately, he realizes too late that each conveyor belt only moves one way, so now travel along each walkway is only possible in a single direction! Now, it is no longer the case that one can travel from any station to any other station.
However, Farmer John thinks that all may not be lost, so long as there is at least one station i such that one can eventually travel to station i from every other station. Note that traveling to station i from another arbitrary station j may involve traveling through intermediate stations between i and j. Please help Farmer John figure out if such a station i exists.
Input
The first line contains an integer N, the number of processing stations. Each of the next N−1 lines contains two space-separated integers ai and bi with 1≤ai,bi≤N and ai≠bi. This indicates that there is a conveyor belt that moves from station ai to station bi, allowing travel only in the direction from ai to bi.
Output
If there exists a station i such that one can walk to station i from any other station, then output the minimal such i. Otherwise, output −1.
Example
inputCopy
3
1 2
3 2
outputCopy
2
分析
以每个点为起点,dfs,把能到的点标记
若一个点被其他n-1个点标记了,说明所有点都能到这个点
代码
#include<iostream>
using namespace std;
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<string>
#include<cmath>
#include<vector>
const int INF=1e9;
const int MAX_N=105;
int cnt[MAX_N];
vector<int> g[MAX_N];
void dfs(int i){
cnt[i]++;
for(int j=0;j<g[i].size();j++){
dfs(g[i][j]);
}
}
int main()
{
int n; scanf("%d",&n);
for(int i=1;i<=n-1;i++) {
int x,y;
scanf("%d%d",&x,&y);
g[x].push_back(y);
}
for(int i=1;i<=n;i++) dfs(i);
int ok=0;
for(int i=1;i<=n;i++) {
if(cnt[i]==n) {ok=1; printf("%d\n",i); break;}
}
//for(int i=1;i<=n;i++) cout<<cnt[i]<<" ";
if(!ok) puts("-1");
return 0;
}
题面
G. Bucket Brigade
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
A fire has broken out on the farm, and the cows are rushing to try and put it out! The farm is described by a 10×10 grid of characters like this: …B…R…L… The character ‘B’ represents the barn, which has just caught on fire. The ‘L’ character represents a lake, and ‘R’ represents the location of a large rock.
The cows want to form a “bucket brigade” by placing themselves along a path between the lake and the barn so that they can pass buckets of water along the path to help extinguish the fire. A bucket can move between cows if they are immediately adjacent in the north, south, east, or west directions. The same is true for a cow next to the lake — the cow can only extract a bucket of water from the lake if she is immediately adjacent to the lake. Similarly, a cow can only throw a bucket of water on the barn if she is immediately adjacent to the barn.
Please help determine the minimum number of ‘.’ squares that should be occupied by cows to form a successful bucket brigade.
A cow cannot be placed on the square containing the large rock, and the barn and lake are guaranteed not to be immediately adjacent to each-other.
Input
The input file contains 10 rows each with 10 characters, describing the layout of the farm.
Output
Output a single integer giving the minimum number of cows needed to form a viable bucket brigade.
Example
inputCopy
…
…
…
…B…
…
…R…
…
…
…L…
…
outputCopy
7
分析
模板题,bfs求最短路
代码
#include<iostream>
using namespace std;
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<string>
#include<cmath>
#include<queue>
const int INF=1e9;
//const int MAX_N=15;
char ch[15][15];
int Y[15][15],sx,sy;
int d[15][15];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
queue<int> que;
int n=10;
bool check(int x,int y){
if(x>=1&&y>=1&&x<=n&&y<=n && ch[x][y]!='R' && d[x][y]==INF) return 1;
return 0;
}
void bfs(){
que.push(sx); que.push(sy);
d[sx][sy]=0;
while(!que.empty()){
int x=que.front(); que.pop();
int y=que.front(); que.pop();
if(ch[x][y]=='B') { printf("%d\n",d[x][y]-1); break; }
for(int i=0;i<4;i++){
int nx=x+dx[i];
int ny=y+dy[i];
if(check(nx,ny)){
que.push(nx);que.push(ny);
d[nx][ny]=d[x][y]+1;
//d[nx][ny]=min( d[nx][ny],d[x][y]+1 );
}
}
}
}
int main()
{
for(int i=1;i<=n;i++) scanf("%s",ch[i]+1);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(ch[i][j]=='L') { sx=i,sy=j; }
d[i][j]=INF;/
}
}
bfs();
return 0;
}
题面
H. I Would Walk 500 Miles
time limit per test1 second
memory limit per test512 megabytes
inputstandard input
outputstandard output
Farmer John wants to divide his N cows (N≤7500), conveniently numbered 1…N, into K non-empty groups (2≤K≤N) such that no two cows from two different groups can interact with each other without walking some number of miles. Cow x and Cow y (where 1≤x<y≤N) are willing to walk (2019201913x+2019201949y) mod 2019201997 miles to see each other.
Given a division of the N cows into K non-empty groups, let M be the minimum of the number of miles any two cows in two different groups are willing to walk to see each other. To test the cows’ devotion to each other, Farmer John wants to optimally divide the N cows into K groups such that M is as large as possible.
Input
The input is just one line, containing N and K, separated by a space.
Output
Print out M in an optimal solution.
Example
inputCopy
3 2
outputCopy
2019201769
分析
打表找规律
相同x,比较y,y越大距离越小
相同y,比较x,x越大距离越小
也就是说,序号越大距离越小
题目要求最大的最小距离,
要保证最小距离,无论n在哪组,n必选
要使最小距离最大,则要使另一个序号最小
先考虑分2组,把最小的1分离,得到1,2~n 这两组
分3组 把最小的1和2分离,得到1,2,3~n三组
分k组 把1到k-1分离,得到1,2…k-1,k~n k组
选择两个不同组的序号最大的数 即选择k-1和 n
代码
#include<iostream>
using namespace std;
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<string>
#include<cmath>
typedef long long ll;
const int INF=1e9;
int main()
{
ll a=2019201913,b=2019201949,mod=2019201997;
/*for(int i=1;i<=10;i++){ //相同i比j 相同j比i 都递减 (即号大距离小)
//for(int j=i+1;j<=10;j++){
//cout<<i<<" "<<j<<" "<< ( a*i+b*j )%mod<<endl;
for(int j=1;j<i;j++){
cout<<j<<" "<<i<<" "<< ( a*j+b*i )%mod<<endl;
}
}*/
int n,k; cin>>n>>k;
cout<<( a*(k-1)+b*n )%mod<<endl;
return 0;
}