VJ第一周个人训练赛

B:暴力模拟

题意:给定X,Y两个砝码的质量,你可以选择一个砝码将其拆成质量为A、B的两个砝码,最终将得到三个砝码,你的任务就是,如何拆分会使得天平能够测得的不同质量数最多

例子:X:4   Y:9

我们可以将X拆分为 1和 3,这样就可以测得的最大质量数为,1,2,3,4,5,6,7,8,9,10,11,12,13。

分析:要想知道如何拆分才会使得质量数最大,那么我们可以通过枚举每一次分法,最终取得max

代码:

#include<bits/stdc++.h>
#define int long long
const int N=2e5+10;
using namespace std;
int a[N],s[N],sum[N];

inline void solve(){
	int x,y;cin>>x>>y;
	int ans=0;
	set<int>se;se.clear();
	//拆砝码x
	for(int i=1;i<=x;i++){
		int a=i,b=x-i,c=y;
		se.insert(a);se.insert(b);se.insert(c);
		se.insert(a+b);se.insert(a+c);se.insert(b+c);se.insert(a+b+c);
		if(a!=b) se.insert(abs(a-b));
		if(a!=c) se.insert(abs(a-c));
		if(b!=c) se.insert(abs(b-c));
		if(a+b!=c) se.insert(abs(a+b-c));
		if(a+c!=b) se.insert(abs(a+c-b));
		if(b+c!=a) se.insert(abs(b+c-a));
 		if(se.size()>ans) ans=se.size();
 		se.clear();
	}
	
	//拆砝码y
	for(int i=1;i<=y;i++){
		int a=i,b=y-i,c=x;
		se.insert(a);se.insert(b);se.insert(c);
		se.insert(a+b);se.insert(a+c);se.insert(b+c);se.insert(a+b+c);
		if(a!=b) se.insert(abs(a-b));
		if(a!=c) se.insert(abs(a-c));
		if(b!=c) se.insert(abs(b-c));
		if(a+b!=c) se.insert(abs(a+b-c));
		if(a+c!=b) se.insert(abs(a+c-b));
		if(b+c!=a) se.insert(abs(b+c-a));
 		if(se.size()>ans) ans=se.size();
 		se.clear();
	}
	cout<<ans<<"\n";
}

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--) solve();
}

D:标记?

题意:数一下有多少种线路,并处以公交车的数量。

分析:依次标记每条路线,记录不同的路线条数,最后除以公交车的数量

代码:

#include<bits/stdc++.h>
#define int long long
const int N=550;
using namespace std;
int x[N],y[N],vis[N][N];//vis记录从x——>y是否走过

inline void solve(){
	int bus,m;cin>>bus>>m;
	memset(vis,0,sizeof vis);
	int res=0;
	for(int i=1;i<=m;i++) cin>>x[i];
	for(int i=1;i<=m;i++) cin>>y[i];
	
	for(int i=1;i<=m;i++){
		if(vis[x[i]][y[i]]==0){
			vis[x[i]][y[i]]=1;
			vis[y[i]][x[i]]=1;
			res++;
		}
	}
	cout<<fixed<<setprecision(3)<<(1.0*res/bus)<<endl;
}

signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--) solve();
}

 F:暴力模拟

题意:一个村长有N个人,M对朋友关系,当i和j的共同朋友数量大于或等于K时,双方可以变成朋友。求一段时间后有多少对新的朋友对关系建立起来。

分析:一开始是以为并查集,然后发现是陷阱。然后别人说可以用图做,用Prim可以求解。这里选择的是暴力模拟。因为数据只有100,O(N^3)并不会超时。

这题的关键:

1:如何判断两人的共同朋友数量

2:如何进行关系合并

3:合并后,如何再判朋友关系的数量

具体看代码:

#include<bits/stdc++.h>
using namespace std;
int f[150][150];

inline void solve(){
	 int n,m,k;cin>>n>>m>>k;
     memset(f,0,sizeof(f));
     for(int i=0;i<m;i++){//处理朋友关系
     	 int x,y;cin>>x>>y;
         f[x][y]=f[y][x]=1;
     }
     int s1=0,s2=0,s3=0;
     while(1){
         s1=0;
         for(int i=0;i<n;i++){//枚举所有人的关系情况
             for(int j=i+1;j<n;j++){
                 if(f[i][j]==0){//如果i跟j不是朋友
                     s2=0;
                     for(int t=0;t<n;t++){//枚举i和j共同朋友
                        if(f[i][t]&&f[j][t]) s2++;//记录共同朋友个数
                    }
                    if(s2>=k){//满足条件
                        s1++;//s1是保证循环结束:即不会再有新朋友结交
                        s3++;//新结交朋友的个数
                        f[i][j]=f[j][i]=1;//i和j成为朋友
                    }
                }
            }
        }
        if(s1==0) break;
    }
    cout<<s3<<"\n";
}

int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int T;cin>>T;
    while(T--) solve();
}

H:贪心

题意:一个音游,分数由point * (combo*2+1)计算,假设玩家很强,combo是一直连续的。求最低分和最高分。point分成50,100,300三种。(注意:combo是从0开始的)

输入:每个point分对应点了几次   输出:min,max

分析:要想使分数最低,肯定是先point分从大到小开始点,分数最高则反之

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;

inline void solve(){
    int a,b,c;cin>>a>>b>>c;
    int d=a+b+c;int aa=a,bb=b,cc=c;
    int minn=0,maxx=0;
    for(int i=0;i<d;i++){
        if(aa) minn+=300*(i*2+1),aa--;
        else if(bb) minn+=100*(i*2+1),bb--;
        else minn+=50*(i*2+1),cc--;
	}
	for(int i=0;i<d;i++){
		if(c) maxx+=50*(i*2+1),c--;
		else if(b) maxx+=100*(i*2+1),b--;
		else maxx+=300*(i*2+1),a--;
	}
	cout<<minn<<" "<<maxx<<"\n";
}

signed main(){
    int t;cin>>t;
    while(t--) solve();
}

J:暴力枚举

题意:给定N个小朋友围成一圈,每个小朋友手上都有对应的玩具数量,老师将抽取M个小朋友手里所有的玩具,问能够抽取的最大数。

分析:直接暴力枚举答案即可

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int a[N];

inline void solve(){
    int n,m;cin>>n>>m;
    for(int i=0;i<n;i++) cin>>a[i];
    int cnt=0,ans=0,res=0;
    for(int i=0;i<n;i++){
    	cnt=0,ans=0;
    	for(int j=i%n;;j++){
    		j%=n;
    		ans+=a[j];cnt++;
    		if(cnt==m) break;
		}
		res=max(res,ans);
	}
    cout<<res<<"\n";
}

signed main(){
    int t;cin>>t;
    while(t--) solve();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值