USACO 12月 2022-2023 December Contest Silver银组 题解

版权声明:本文为CSDN博主「GeekAlice」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

目录

Problem 1. Barn Tree

Problem 2. Circular Barn

Problem 3. Range Reconstruction


Problem 1. Barn Tree

Farmer John's farm has NN barns (2≤N≤2⋅1052≤N≤2⋅105) numbered 1…N1…N. There are N−1N−1 roads, where each road connects two barns and it is possible to get from any barn to any other barn via some sequence of roads. Currently, the jjth barn has hjhj hay bales (1≤hj≤1091≤hj≤109).

To please his cows, Farmer John would like to move the hay such that each barn has an equal number of bales. He can select any pair of barns connected by a road and order his farmhands to move any positive integer number of bales less than or equal to the number of bales currently at the first barn from the first barn to the second.

Please determine a sequence of orders Farmer John can issue to complete the task in the minimum possible number of orders. It is guaranteed that a sequence of orders exists.

INPUT FORMAT (input arrives from the terminal / stdin):

The first line of input contains the value of N.N.

The second line of input contains the space-separated values of hjhj for j=1…Nj=1…N.

The final N−1N−1 lines of input each contain two space-separated barn numbers ui viui vi, indicating that there is a bidirectional road connecting uiui and vivi.

OUTPUT FORMAT (print output to the terminal / stdout):

Output the minimum possible number of orders, followed a sequence of orders of that length, one per line.

Each order should be formatted as three space-separated positive integers: the source barn, the destination barn, and the third describes the number of hay bales to move from the source to the destination.

If there are multiple solutions, output any.

SAMPLE INPUT:

4
2 1 4 5
1 2
2 3
2 4

SAMPLE OUTPUT:

3
3 2 1
4 2 2
2 1 1

In this example, there are a total of twelve hay bales and four barns, meaning each barn must have three hay bales at the end. The sequence of orders in the sample output can be verbally translated as below:

  1. From barn 33 to barn 22, move 11 bale.
  2. From barn 44 to barn 22, move 22 bales.
  3. From barn 22 to barn 11, move 11 bale.

SCORING:

  • Test cases 2-8 satisfy N≤5000N≤5000
  • Test cases 7-10 satisfy vi=ui+1vi=ui+1
  • Test cases 11-16 satisfy no additional constraints

#include<bits/stdc++.h>
using namespace std;          
#define mpp(a,b,c) make_pair(a,make_pair(b,c))
#define _1 first
#define _2 second.first
#define _3 second.second   
#define pb push_back 
#define eb emplace_back  
#define int long long
namespace IO{
    inline int read(){
    	int ans=0,flag=1;
    	char ch=getchar();
    	while(!isdigit(ch)){
    	    if(ch=='-')flag=-1;  
    	    ch=getchar();
    	}
    	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    	return ans*flag;
    }
    inline string reads(){
    	string ans="";char ch=getchar();
    	while(ch==' '||ch=='\n')
    	    ch=getchar();
    	while(ch!=' '&&ch!='\n')
    	    ans+=ch,ch=getchar();  
    	return ans;
    }
    inline char readc(){
    	char ch=getchar();
    	while(ch==' '||ch=='\n')
    	    ch=getchar();
    	return ch;
    }
    inline int sqr(int x){
        return x*x;
    }
    inline void reada(int *a,int len){
        for(int i=1;i<=len;i++)
        a[i]=read();
    }  
    void write(int x){
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	return;
    }
}
using IO::read;
const int N=4e5+7; 
bool mem1=0,mem2=0;
int Datas=0,T=1,n,avg=0,h[N];  
vector<int>g[N]; 
long long ned[N];  
vector<pair<int,pair<int,long long> > >opt;
void solve(int u,int fa){
	for(auto v:g[u]){
		if(v==fa||ned[v]<=0)continue;
		opt.eb(mpp(u,v,ned[v]));
		solve(v,u); 
	}
}
void dfs(int u,int fa){ 
	for(auto v:g[u]){
	    if(v==fa)
	    continue;
	    dfs(v,u); 
	}
	for(auto v:g[u]){
	    if(v==fa)continue;
	    ned[u]+=ned[v];
	}
	ned[u]+=avg-h[u];
	if(ned[u]<=0){
	    solve(u,fa);
	    if(ned[u]!=0) 
	    opt.eb(mpp(u,fa,-ned[u]));
	}
}
void Main(){
	n=read();
	long long sum=0;
	for(int i=1;i<=n;i++)h[i]=read(),sum+=h[i];
	avg=sum/n;
	for(int i=1;i<n;i++){
		int u=read(),v=read(); 
		g[u].pb(v),g[v].pb(u);
	}dfs(1,0);
	printf("%lld\n",(int)(opt.size()));
	for(auto x:opt){
		printf("%lld %lld %lld\n",x._1,x._2,x._3);
	}
	return;
} 
signed main(){
#ifdef EXODUS
	printf("%.5lfMB\n",abs(&mem2-&mem1)/1024.0/1024.0);
	freopen("Data.in","r",stdin);
	freopen("Code.out","w",stdout); 
#endif
#ifdef online_judge
	freopen("input.in","r",stdin);
	freopen("user_out.out","w",stdout); 
#endif
	if(Datas)T=read();
	while(T--)Main();
#ifdef EXODUS
	cerr<<clock()<<"ms"<<endl; 
#endif
	return 0; 
} 

Problem 2. Circular Barn

Farmer John and his archnemesis Farmer Nhoj are playing a game in a circular barn. There are NN (1≤N≤1051≤N≤105) rooms in the barn, and the iith room initially contains aiai cows (1≤ai≤5⋅1061≤ai≤5⋅106). The game is played as follows:

  • Both farmers will always be in the same room. After entering a room, each farmer takes exactly one turn, with Farmer John going first. Both farmers initially enter room 11.
  • If there are zero cows in the current room, then the farmer to go loses. Otherwise, the farmer to go chooses an integer PP, where PP must either be 11 or a prime number at most the number of cows in the current room, and removes PP cows from the current room.
  • After both farmers have taken turns, both farmers move to the next room in the circular barn. That is, if the farmers are in room ii, then they move to room i+1i+1, unless they are in room NN, in which case they move to room 11.

Determine the farmer that wins the game if both farmers play optimally.

INPUT FORMAT (input arrives from the terminal / stdin):

The input contains TT test cases. The first line contains TT (1≤T≤10001≤T≤1000). Each of the TT test cases follow.

Each test case starts with a line containing NN, followed by a line containing a1,…,aNa1,…,aN.

It is guaranteed that the sum of all NN is at most 2⋅1052⋅105.

OUTPUT FORMAT (print output to the terminal / stdout):

For each test case, output the farmer that wins the game, either "Farmer John" or "Farmer Nhoj."

SAMPLE INPUT:

5
1
4
1
9
2
2 3
2
7 10
3
4 9 4

SAMPLE OUTPUT:

Farmer Nhoj
Farmer John
Farmer John
Farmer John
Farmer Nhoj

For the first test case, Farmer John can remove 11, 22, or 33 cows from the first room. Whichever number he removes, Nhoj can remove the remaining cow(s), forcing FJ to lose when they circle back to the first room.

For the second test case, FJ can remove 55 cows, forcing Nhoj to work with only 44 cows remaining. Now, Nhoj can either remove 11, 22, or 33 cows. This is now similar to the first test case.

For the third and fourth test cases, FJ can immediately remove all the cows from the first room, forcing Nhoj to lose.

For the fifth test case, FJ can remove 11, 22, or 33, cows from the first room, and Nhoj can remove the rest right after. When they circle back around to the first room, FJ will lose.

SCORING:

  • Inputs 2-4 satisfy N=1N=1.
  • Inputs 1, 2, and 5-7 satisfy ai≤1000ai≤1000.
  • Inputs 8-20 satisfy no additional constraints.
#include<bits/stdc++.h>
using namespace std;  
#define il inline   
#define np pair<int,int> 
#define mp(a,b) make_pair(a,b)     
namespace IO{
    il int read(){
    	int ans=0,flag=1;
    	char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')flag=-1;ch=getchar();}
    	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    	return ans*flag;
    }
    il string reads(){
    	string ans="";char ch=getchar();
    	while(ch==' '||ch=='\n')ch=getchar();
    	while(ch!=' '&&ch!='\n')ans+=ch,ch=getchar();
    	return ans;
    }
    il char readc(){
    	char ch=getchar();
    	while(ch==' '||ch=='\n')ch=getchar();
    	return ch;
    }
    il int sqr(int x){return x*x;}
    il void reada(int *a,int len){for(int i=1;i<=len;i++)a[i]=read();}
    void write(int x){
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	return;
    }
}
using IO::read;
bool mem1=0;
int Datas=1,T=1;
const int N=5e6+7,P=5e6+7;
int pri[P],cnt=0,n,a[N];
bool chk[N]; 
void get_prime(int Up){
	chk[1]=0;pri[++cnt]=1;
	for(int i=2;i<=Up;i++){
		if(!chk[i])pri[++cnt]=i;
		for(int j=2;j<=cnt&&pri[j]*i<=Up;j++){
		    chk[i*pri[j]]=1;
		    if(i%pri[j]==0)
		    break;
		}
	}
} 
int res[N];
bool mem2=0;
void Main(){
	n=read();
	for(int i=1;i<=n;i++){
		a[i]=read();
	}
	np tim1=mp(2e9,2e9),tim2=mp(2e9,2e9);
	for(int i=1;i<=n;i++){
		if(a[i]%4==0){
			tim1=min(tim1,mp(a[i]/2/2+1,i));
		}else{
			if(a[i]&1^1)tim2=min(tim2,mp((a[i]/2+1)/2,i));
			 else{ 
				if(res[a[i]])tim2=min(tim2,mp((res[a[i]]+1)/2,i));
				else{
					for(int j=0;j<=a[i];j+=4){
						if(!chk[a[i]-j]){
							res[a[i]]=j/2+1; 
							break; 
						}
					}
					tim2=min(tim2,mp((res[a[i]]+1)/2,i));
				}
			}
		}
	}
	if(tim1<tim2)puts("Farmer Nhoj");
	else puts("Farmer John");
	return;
} 
int main(){
	get_prime(5e6);
#ifdef EXODUS
	printf("%.5lfMB\n",abs(&mem2-&mem1)/1024.0/1024.0);
	freopen("Data.in","r",stdin);
	freopen("Code.out","w",stdout);
#endif
#ifdef online_judge
	freopen("input.in","r",stdin);
	freopen("user_out.out","w",stdout);
#endif
	if(Datas)T=read();
	while(T--)Main();
#ifdef EXODUS
	cerr<<clock()<<"ms"<<endl;
#endif
	return 0;
} 

 

Problem 3. Range Reconstruction

Bessie has an array a1,…,aNa1,…,aN, where 1≤N≤3001≤N≤300 and 0≤ai≤1090≤ai≤109 for all ii. She won't tell you aa itself, but she will tell you the range of each subarray of aa. That is, for each pair of indices i≤ji≤j, Bessie tells you ri,j=maxa[i…j]−mina[i…j]ri,j=maxa[i…j]−mina[i…j]. Given these values of rr, please construct an array that could have been Bessie's original array. The values in your array should be in the range [−109,109][−109,109].

INPUT FORMAT (input arrives from the terminal / stdin):

The first line contains NN.

Another NN lines follow. The iith of these lines contains the integers ri,i,ri,i+1,…,ri,Nri,i,ri,i+1,…,ri,N.

It is guaranteed that there is some array aa with values in the range [0,109][0,109] such that for all i≤ji≤j, ri,j=maxa[i…j]−mina[i…j]ri,j=maxa[i…j]−mina[i…j].

OUTPUT FORMAT (print output to the terminal / stdout):

Output one line containing NN integers b1,b2,…,bNb1,b2,…,bN in the range [−109,109][−109,109] representing your array. They must satisfy ri,j=maxb[i…j]−minb[i…j]ri,j=maxb[i…j]−minb[i…j] for all i≤ji≤j.

SAMPLE INPUT:

3
0 2 2
0 1
0

SAMPLE OUTPUT:

1 3 2

For example, r1,3=maxa[1…3]−mina[1…3]=3−1=2r1,3=maxa[1…3]−mina[1…3]=3−1=2.

SAMPLE INPUT:

3
0 1 1
0 0
0

SAMPLE OUTPUT:

0 1 1

This example satisfies the constraints for subtask 1.

SAMPLE INPUT:

4
0 1 2 2
0 1 1
0 1
0

SAMPLE OUTPUT:

1 2 3 2

This example satisfies the constraints for subtask 2.

SAMPLE INPUT:

4
0 1 1 2
0 0 2
0 2
0

SAMPLE OUTPUT:

1 2 2 0

SCORING:

  • Test 5 satisfies r1,N≤1r1,N≤1.
  • Tests 6-8 satisfy ri,i+1=1ri,i+1=1 for all 1≤i<N1≤i<N.
  • Tests 9-14 satisfy no additional constraints.
#include<bits/stdc++.h>
using namespace std; 
const int inf=0x3f3f3f3f;
const int Maxn=310;
int n,a[Maxn][Maxn],ans[Maxn],minn[Maxn],maxn[Maxn];
bool vis[Maxn];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++)for(int j=i;j<=n;j++) scanf("%d",&a[i][j]); 
	int pos=n;
	ans[pos]=0;
	int minn=0,maxx=0;
	memset(vis,-1,sizeof(vis));
	pos--;
	while(pos!=0){
		int ans1=ans[pos+1]+a[pos][pos+1],ans2=ans[pos+1]-a[pos][pos+1]; 
		int minn1=ans1,maxn1=ans1;
		int minn2=ans2,maxn2=ans2; 
		bool flag1=1,flag2=1;
		for(int i=pos+1;i<=n;i++)
		{
			minn1=min(minn1,ans[i]);minn2=min(minn2,ans[i]);
			maxn1=max(maxn1,ans[i]);maxn2=max(maxn2,ans[i]);
			if(maxn2-minn2!=a[pos][i]) flag2=0;  
			if(maxn1-minn1!=a[pos][i]) flag1=0; 
		}
		if(!flag1 && !flag2)
		{  
			pos++;
			vis[pos]=-1;
			continue;
		}
		if(flag1 && !flag2)
		{
			ans[pos]=ans1;
			pos--;
		}else if(flag2 && !flag1){
			ans[pos]=ans2;
			pos--;
		}else if(flag1 && flag2){
			if(vis[pos]==-1)
			{
				ans[pos]=ans1;
				vis[pos]=1;
				pos--;
			}else{
				ans[pos]=ans2;
				vis[pos]=2;
				pos--;
			}
		}
	}
	int awa=inf;
	for(int i=1;i<=n;i++)awa=min(awa,ans[i]); 
	for(int i=1;i<n;i++)printf("%d ",ans[i]-awa); 
	printf("%d\n",ans[n]-awa);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/GeekAlice/article/details/128368949
今日推荐