首页 > 其他分享 >231019校内赛

231019校内赛

时间:2023-10-19 19:45:15浏览次数:50  
标签:校内 int cin long 231019 return col define

T1 购买饮料

piiSecd.jpg

题解

简单且傻逼的题目有人更傻逼没做出来

很容易就会想去拿最后能喝多少瓶去做未知量来求

然后就有一个严重的问题,它会赊账

非常明显这样算是不得行的

那么考虑换个思路

以能喝多少套饮料为未知量,先除去第一套,免得一套都买不起时赊账买了饮料

然后将剩余的钱除以 \(a\times x - b\) 顺带判一下无解,式子很简单就不解释了

那么我们得出来了这个值就很容易求出到底喝了多少瓶了

别忘了最后要统计一下最后凑不够一套时的瓶数

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,x,a,b;
signed main(){
	freopen("buy.in","r",stdin);
	freopen("buy.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--){
		cin>>n>>x>>a>>b;
		if(n<a*x){
			cout<<n/x<<"\n";
			continue;
		}
		if(a*x<=b){
			cout<<"-1\n";
			continue;
		}
		int t = (n-a*x)/(a*x-b)+1;
		cout<<t*a+(n-t*(a*x-b))/x<<"\n";
	}
	return 0;
}

第二种是用二分找答案的方法,仅供参考

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,x,a,b;
signed main(){
	freopen("buy.in","r",stdin);
	freopen("buy.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--){
		cin>>n>>x>>a>>b;
		if(a*x<=b&&n>=a*x){
			 cout<<"-1\n";
			continue;
		}
		if((n/x)<a){
			cout<<n/x<<"\n";
			continue;
		}
		int l = 0,r = 1e9;
		while(l<r){
			int mid = l+r>>1;
			if(n-mid*(a*x-b)>=a*x) l = mid+1;
			else r = mid;
		}
		cout<<(n-r*(a*x-b))/x+r*a<<"\n";
	}
	return 0;
}

T2 多边形

piiS6gJ.jpg

题解

一道构造题,偏向训练思维

如果存在一个颜色只出现了一次,那么直接把这个点和所有其他点相连即可

否则一定会出现相邻的三个点颜色两两不同,直接将这三个点划分成一个三角形,并删除掉中间那个点递归即可

容易发现所有限制条件始终满足。需要用链表来维护当前所有没有被删除的点

代码上没有什么难度

#include<bits/stdc++.h>
#define N ((int)1e6+10)
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
int n,col[N<<1],u[N],v[N],stk[N],top;
char c[N];
vector<pii>ans;
int ne(int x){
	return x==n?1:x+1; 
}
int be(int x){
	return x==1?n:x-1;
}
bool check(int x,int y,int z){
	return col[x]!=col[y]&&col[x]!=col[z]&&col[y]!=col[z];
}
int main(){
	freopen("polygon.in","r",stdin);
	freopen("polygon.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin>>n>>c+1;
	for(int i = 1;i<=n;i++){
		if(c[i]=='R') col[i] = 1;
		if(c[i]=='B') col[i] = 2;
		if(c[i]=='G') col[i] = 3;
	}
	int q = -1;
	for(int i = 1;i<=n;i++){
		if(check(be(i),i,ne(i))){
			q = ne(i);
			break;
		}
	}
	stk[++top] = q;
	for(int i = ne(q);i!=q;i = ne(i)){
		while(top>=2&&check(stk[top-1],stk[top],i)){
			ans.push_back({stk[top-1],i});
			top--;
		}
		stk[++top] = i;
	}
	for(int i = 0;i<=n-4;i++)
		cout<<ans[i].fi<<" "<<ans[i].se<<"\n";
	return 0;
}

T3 二分图最大权匹配

piiyvjI.jpg

题解

没改,不过需要先知道曼哈顿距离转切比雪夫距离

之前有一场考试中有相应模板,可以自行翻一下如果没看见就是我把那篇博客咕了

pii6CE8.png

#include<bits/stdc++.h>

#define pb push_back
#define fi first
#define se second
#define mp make_pair

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef long double ld;

template <typename T> bool chkmin(T &x,T y){return x>y?x=y,1:0;}
template <typename T> bool chkmax(T &x,T y){return x<y?x=y,1:0;}

int readint(){
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

const ll inf=1ll<<60;
int n;
ll ax[100005],ay[100005],bx[100005],by[100005],vin[100005][5],vout[100005][5],din[5],dout[5],dis[5][5];
set<pll> in[5],out[5],e[5][5];

void delin(int x,int y){
	for(int i=1;i<=4;i++) in[i].erase(mp(vin[x][i],x));
	for(int i=1;i<=4;i++) din[i]=in[i].empty()?inf:in[i].begin()->fi;
	for(int i=1;i<=4;i++) if(i!=y) e[y][i].insert(mp(vin[x][i]-vin[x][y],x));
}

void delout(int x,int y){
	for(int i=1;i<=4;i++) out[i].erase(mp(vout[x][i],x));
	for(int i=1;i<=4;i++) dout[i]=out[i].empty()?inf:out[i].begin()->fi;
	for(int i=1;i<=4;i++) if(i!=y) e[i][y].insert(mp(vout[x][i]-vout[x][y],-x));
}

void deledge(int x,int y){
	int z=e[x][y].begin()->se;
	if(z>0){
		for(int i=1;i<=4;i++) if(i!=x) e[x][i].erase(mp(vin[z][i]-vin[z][x],z));
		for(int i=1;i<=4;i++) if(i!=y) e[y][i].insert(mp(vin[z][i]-vin[z][y],z));
	}
	else{
		z=-z;
		for(int i=1;i<=4;i++) if(i!=y) e[i][y].erase(mp(vout[z][i]-vout[z][y],-z));
		for(int i=1;i<=4;i++) if(i!=x) e[i][x].insert(mp(vout[z][i]-vout[z][x],-z));
	}
}

ll f(int x,int y){return e[x][y].empty()?inf:e[x][y].begin()->fi;}

void delpath(int x,int y){
	if(x==y) return;
	int z=0,w=0;
	for(int i=1;i<=4;i++){
		if(i==x||i==y) continue;
		if(!z) z=i;
		else w=i;
	}
	ll mina=f(x,y); int opt=1;
	if(chkmin(mina,f(x,z)+f(z,y))) opt=2;
	if(chkmin(mina,f(x,w)+f(w,y))) opt=3;
	if(chkmin(mina,f(x,z)+f(z,w)+f(w,y))) opt=4;
	if(chkmin(mina,f(x,w)+f(w,z)+f(z,y))) opt=5;
	if(opt==1) deledge(x,y);
	if(opt==2) deledge(x,z),deledge(z,y);
	if(opt==3) deledge(x,w),deledge(w,y);
	if(opt==4) deledge(x,z),deledge(z,w),deledge(w,y);
	if(opt==5) deledge(x,w),deledge(w,z),deledge(z,y);
}

void calc(){
	for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) dis[i][j]=i==j?0:f(i,j);
	for(int k=1;k<=4;k++) for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) chkmin(dis[i][j],dis[i][k]+dis[k][j]);
}

int main(){
	freopen("match.in","r",stdin);freopen("match.out","w",stdout);
	n=readint();
	for(int i=1;i<=n;i++) ax[i]=readint(),ay[i]=readint();
	for(int i=1;i<=n;i++) bx[i]=readint(),by[i]=readint();
	for(int i=1;i<=n;i++){
		int x=ax[i],y=ay[i];
		ax[i]=x+y,ay[i]=x-y;
		x=bx[i],y=by[i];
		bx[i]=x+y,by[i]=x-y;
	}
	for(int i=1;i<=n;i++){
		vin[i][1]=ax[i];
		vin[i][2]=-ax[i];
		vin[i][3]=ay[i];
		vin[i][4]=-ay[i];
		vout[i][1]=-bx[i];
		vout[i][2]=bx[i];
		vout[i][3]=-by[i];
		vout[i][4]=by[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=4;j++){
			in[j].insert(mp(vin[i][j],i));
			out[j].insert(mp(vout[i][j],i));
		}
	}
	for(int i=1;i<=4;i++) for(int j=1;j<=4;j++) dis[i][j]=i==j?0:inf;
	for(int i=1;i<=4;i++){
		din[i]=in[i].begin()->fi;
		dout[i]=out[i].begin()->fi;
	}
	ll ans=0;
	for(int i=1;i<=n;i++){
		ll mn=inf; pii opt=mp(0,0);
		for(int j=1;j<=4;j++)
			for(int k=1;k<=4;k++)
				if(chkmin(mn,din[j]+dis[j][k]+dout[k])) opt=mp(j,k);
		ans-=mn;
		int x=in[opt.fi].begin()->se,y=out[opt.se].begin()->se;
		delin(x,opt.fi);
		delout(y,opt.se);
		delpath(opt.fi,opt.se);
		calc();
	}
	printf("%lld\n",ans);
	return 0;
}

还想看我改T4?没门!

不过T4随机38分,属实难见

标签:校内,int,cin,long,231019,return,col,define
From: https://www.cnblogs.com/cztq/p/17775461.html

相关文章

  • [校内]此方(konata)
    2023-10-14题目LittleBrother题目描述难度&重要性(1~10):7题目来源CQYC题目算法几何,二分解题思路Sol我们知道,对于两个圆,我们无非就只有三种情况:相离,相切,相交。而这道题目是不允许其他圆相交,而两个圆不相交只有两种情况:包含,不包含。根据垂径定理得知,过线段两端的圆的......
  • 231011校内赛
    T1树上的数题解比上一次好一些的第一题不过我还是没做出来一眼树形\(dp\)不过状态设计和转移不是很好列容易想到对于子树枚举,记录\(f_{i,j}\)表示\(i\)的子树空出了\(j\)个点时的方案数对于每一个节点的初始状态都是\(f_{i,0}=n-dep_i\\\f_{i,1}=1\)为......
  • 231009校内赛
    T1里群题解阴间第一题题目中有一个很明显的建图方法就是对于第\(i\)天入群的人在第\(j\)天退群那么就在\(i,j\)之间连一条边首先有一个结论,管理员个数不大于\(3\)对于这个结论,证明如下:首先第一次删除出现后就一定需要两个管理员了如果某次删除只删掉了某一个管理......
  • 231007校内赛
    T1karma题解首先从贪心的思路出发把所有零多的字符串放在前面,但如下一组数据便可以卡掉201100接着我们可以来思考对于贪心的更改多举几组不同的可以卡掉的样例后可以发现如下规律先将所有字符串按\(0\)的数量排一遍序对于每一个字符串的\(0\)和\(1\)的数量我......
  • 231004校内赛
    T1水管题解很简单的一道题,别想复杂了只要一边\(dfs\)即可先将当前点的所有水量给出去,如果缺水就给出去负数那么等到最后一个节点如果不是刚好合适,那么就把剩余水量回溯回来,无论正负再如此给下一个连边的点如果最后一个点刚好合适那么给下一个点的就是\(0\)实现很简单......
  • 231002校内赛
    T1数独题解十分简单的一道模拟题有sb少打了一个换行挂50分#include<bits/stdc++.h>#defineN15usingnamespacestd;structnode{ inta[N][N],be;}t[N*10];intT,n=9,q;intferror(intcnt,intx,inty,intk){ for(inti=1;i<=n;i++) if(t[cnt].a[x][i]==k)......
  • 230930校内赛
    T1洛阳怀题解首先非常容易求出的是所有的\(\gcd\)对于\(\gcd\)而言,如果它的分数是负数,那么将它除去一定会使这个数列得分变大所以只用求出所有的\(\gcd\)的分数并判断正负以及是否除过当前答案了就可以了还有一点是因为\(\gcd\)是单调不降的,所以可以从后往前查保证......
  • 2023年中国高校计算机大赛-团队程序设计天梯赛(GPLT)上海理工大学校内选拔赛(同步赛)
    A.AXorBProblem(计数)输入511223输出9说明点击查看代码#include<bits/stdc++.h>#defineIOSios::sync_with_stdio(false);cin.tie(0),cout.tie(0)#defineintlonglongusingnamespacestd;constintN=2e5+10;unordered_map<int,int>......
  • 230925校内赛
    T1开挂我卢本伟没有开挂题解挺简单的,不过我写的比较麻烦因为我们需要让多的尽可能多来让少的尽可能少,所以会想到用栈来存储需要更改的数,靠近栈底就需要更多次数来更改,栈顶则更少最后只用记录下来所有的次数并按从多到少依次分配从小到大的修改代价#include<bits/stdc++.h......
  • 230927校内赛
    T1集合题解很明显的一道树形\(dp\)题我也没看出来dalao们说有一道\(ddp\)的题转移方式一模一样于是都切了,就我是sb首先有一个非常明显的性质在于所有的被选的点一定是可以构成一颗连通子树的最终选取的\(k\)个点一定是从这颗子树中最远点对的一个点沿着这颗子树直......