首页 > 其他分享 >[题解]ABC374 A~E

[题解]ABC374 A~E

时间:2024-10-06 11:12:04浏览次数:9  
标签:int 题解 复杂度 long 枚举 ans ABC374 define

A - Takahashi san 2

直接判断字符串是否以san结尾即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	string s;
	cin>>s;
	int n=s.size();
	if(s[n-1]=='n'&&s[n-2]=='a'&&s[n-3]=='s') cout<<"Yes";
	else cout<<"No";
	return 0;
}

B - Unvarnished Report

用特殊符号将两个字符串补到相同长度,然后逐位判断即可。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
string s,t;
int main(){
	cin>>s>>t;
	int n=max(s.size(),t.size());
	s.resize(n,'*'),t.resize(n,'*');
	if(s==t) cout<<"0\n";
	else{
		for(int i=0;i<n;i++){
			if(s[i]!=t[i]){
				cout<<i+1<<"\n";
				break;
			}
		}
	}
	return 0;
}

C - Separated Lunch

\(2^N\)枚举哪些人分配到A组即可,剩下人分到B组。

点击查看代码
#include<bits/stdc++.h>
#define N 30
#define int long long
using namespace std;
int n,a[N],ans=LLONG_MAX;
signed main(){
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	for(int i=(1<<n)-1;i>=0;i--){
		int cnta=0,cntb=0;
		for(int j=0;j<n;j++){
			if(i&(1<<j)) cnta+=a[j];
			else cntb+=a[j];
		}
		ans=min(ans,max(cnta,cntb));
	}
	cout<<ans;
	return 0;
}

D - Laser Marking

先\(n!\)暴力枚举打印顺序,然后再\(2^n\)枚举每条线段起始端点。然后就以\(O(2^n\times n!)\)的优秀(大嘘)时间复杂度通过了

嘛,反正是暴搜题,能过就行(^^;

此题也有\(O(n^2\times 2^n)\)的做法,见https://atcoder.jp/contests/abc374/editorial/11105,如果有空会回来补这种做法的。

点击查看代码
#include<bits/stdc++.h>
#define N 10
#define int long long
using namespace std;
int n,s,t,sx[N],sy[N],tx[N],ty[N],tmp[N];
double ans=1e18;
double dist(int sx,int sy,int tx,int ty){
	int x=sx-tx,y=sy-ty;
	return sqrt(x*x+y*y);
}
double solve(){
	int x=0,y=0;
	double ans=0;
	for(int ti=0;ti<n;ti++){
		int i=tmp[ti];
		ans+=dist(x,y,sx[i],sy[i])/(1.0*s);
		ans+=dist(sx[i],sy[i],tx[i],ty[i])/(1.0*t);
		x=tx[i],y=ty[i];
	}
	return ans;
}
signed main(){
	cin>>n>>s>>t;
	for(int i=0;i<n;i++){
		cin>>sx[i]>>sy[i]>>tx[i]>>ty[i];
	}
	for(int i=0;i<n;i++) tmp[i]=i;
	do{
		for(int i=(1<<n)-1;i>=0;i--){
			for(int j=0;j<n;j++){
				if((1<<j)&i){
					swap(tx[j],sx[j]);
					swap(ty[j],sy[j]);
				}
			}
			ans=min(ans,solve());
			for(int j=0;j<n;j++){
				if((1<<j)&i){
					swap(tx[j],sx[j]);
					swap(ty[j],sy[j]);
				}
			}
		}
	}while(next_permutation(tmp,tmp+n));
	cout<<fixed<<setprecision(10)<<ans<<"\n";
	return 0;
}

E - Sensor Optimization Dilemma 2

看到需要最大化最小值,于是考虑二分答案\(ans\),判断使得每个工序的生产能力都达到\(ans\)以上所需要付出的最小钱数是否在\(X\)以内。

难点在于计算当前工序达到\(ans\)的生产能力所需要的最小钱数,如果和背包一样,用\(f[i][j]\)表示正在考虑第\(i\)台机器,达到\(j\)的生产能力所需要的最少钱数,处理每个工序时间复杂度将是\(O(V)\),其中\(V\)与\(A\times X=10^9\)同阶,表示答案的值域;即使交换键值,处理每个工序的时间复杂度也会达到\(O(X)\),总时间复杂度\(O(nX\log V)\),无法通过。

我们可以直接枚举\(S\)机器的个数,有一个结论,假设\(S\)是成本较高的那台机器,那么只需要枚举\(S\)的台数从\(0\)到\(\frac{D}{A}-1\),其中\(D=\text{lcm}(A,B)\)。理解起来不难,先把\(ans\)中整的\(D\)全用成本较低的机器达成,对于剩余的零头,再枚举用多少台成本较高的机器。这一步的时间复杂度和\(A\)、\(B\)是同阶的。

代码为了方便直接设\(D=A\times B\),也没判断哪个机器成本更低,用\(2\)次循环把\(S,T\)都枚举了一遍(只是因为懒而已)。不影响复杂度:\(O(nA\log V)\)。

点击查看代码
#include<bits/stdc++.h>
#define int long long
#define N 110
using namespace std;
int n,x,a[N],b[N],p[N],q[N];
bool check(int w){
	int ans=0;
	for(int i=1;i<=n;i++){
		int money=LLONG_MAX;//j是S的个数,k是T的个数
		for(int j=0;j<=b[i]&&j*a[i]<=w;j++){
			int k=(w-j*a[i]+b[i]-1)/b[i];
			money=min(money,j*p[i]+k*q[i]);
		}
		for(int k=0;k<=a[i]&&k*b[i]<=w;k++){
			int j=(w-k*b[i]+a[i]-1)/a[i];
			money=min(money,j*p[i]+k*q[i]);
		}
		ans+=money;
		if(ans>x) return 0;
	}
	return 1;
}
signed main(){
	cin>>n>>x;
	for(int i=1;i<=n;i++) cin>>a[i]>>p[i]>>b[i]>>q[i];
	int l=0,r=1e9;
	while(l<r){
		int mid=(l+r+1)>>1;
		if(check(mid)) l=mid;
		else r=mid-1;
	}
	cout<<l;
	return 0;
}

标签:int,题解,复杂度,long,枚举,ans,ABC374,define
From: https://www.cnblogs.com/Sinktank/p/18448847

相关文章

  • P11059 [入门赛 #27] 数字 (Hard Ver.)题解
    Solution先读题:在给定x的位数\(n\)和模数\(p\)后,要求构造一个\(x\)在满足\(x\modp\)的余数尽可能小的前提下使\(x\)的数字尽可能小。我们假设\(x\)的各位数字之和为\(m\),有\(1\lem\le9n\)。.(当\(x\)仅在最高位有1时\(m=1\),称为情况一,当x每位为9时\(m=9n\),称为情况二......
  • ABC374E 题解
    好题。爱做。标签:二分。求最大的最小值,考虑二分答案。然后问题就转化成了(求\(n\)次):有两种物品,每种物品有一个代价和价值,求获得不少于给定价值所需的最小代价。下文记物品的代价为\(w\),价值为\(v\),所拿的数量为\(cnt\)。假设有两种物品\(S\)与\(T\),\(S\)物品的性价比......
  • P10678 『STA - R6』月 题解
    Solution看了别的大佬的题解,感觉都是数学证明然后用树和图做的,看不懂啊。。。萌新瑟瑟发抖用vector模拟树,然后贪心摸索做出来了。注意到要求最深叶子结点和最浅叶子结点的距离最短时的情况,那么此时根节点应该是树中度数最大的点,把树尽可能的拓宽,深度换宽度。那么同理的根节点......
  • 题解:P11008 『STA - R7』异或生成序列
    Solution序列\(p\)是\(1\)~\(n\)的排列,因此考虑搜索回溯。由\(\sumn\le2\times10^6\)得知\(O(n^2)\)会炸,深感遗憾但仍考虑剪枝。坚信深搜过百万的蒟蒻。。。原\(b\)序列为长度\(n-1\)的序列:{\(b_1,b_2,b_3\cdotsb_n-1\)}将其前面插入一个元素\(......
  • 题解:AT_abc374_d [ABC374D] Laser Marking
    看到\(n\le6\),就知道这道题又是一道搜索了。题面有点长,信息也给的有点多,但稍微分析就可以得到只需要搜索印刷线段的顺序即可。具体的,我们在深搜函数里面传\(4\)个参数,分别代表已选线段的数量,当前位置的横纵坐标,以及当前时间。为了方便,我们表示的是已经印刷完当前线段后的时间......
  • P5593 题解
    题目分析首先考虑什么样的颜色能被链覆盖。容易想到当某种颜色恰巧在一条链上会被覆盖。所以只需要判断一种颜色是否能构成链即可,链的贡献也很好计算。算法考虑链的性质:有且仅有两个端点。凭借这个性质,可以判断一种颜色是否在一条链上。在dfs中考虑各种情况。假设一个......
  • P10418 [蓝桥杯 2023 国 A] 相连的边 题解
    一个比较有趣的树形DP,情况比较多。【题目简述】给定一棵树,求三条相连的边,其边权之和最大。【思路】以X代表当前节点,S表示儿子,G表示孙子,P表示父节点。首先把树建出来,在以下图中,我们模拟二号点的DP过程,考虑以下几种情况:有一条边指向父节点时FG(FatherGrandson):一......
  • 数列 题解
    题意给出一张联通图,图上每个点有红蓝两色,给每一条边都赋一个权值,使得所有的红边构成一颗最小生成树,且权值是\(1\)到\(m\)的排列,求字典序最小的情况。题解对于一条蓝边,其权值一定小于除它以外全是红边的环上的所有红边的权值(有点绕),否则就构不成一颗生成树。所以只需要按顺......
  • CF946G Almost Increasing Array 题解
    题目传送门前置知识最长不下降子序列|权值树状数组及应用解法若将\(\{a\}\)变成严格递增序列,至少需要更改\(n\)减去\(\{a_{i}-i\}\)的最长不下降子序列长度个数。证明对于\(a_{i},a_{j}(i<j)\)若都在最终的严格递增序列里,则有\(a_{i}-a_{j}\lei-j\),即\(......
  • PHP报错getimagesize(): SSL operation failed with code 1问题解决方案
    这个PHP错误通常发生在尝试通过HTTPS协议获取图像时,由于缺少或过期的CA证书导致SSL连接验证失败。以下是详细的解决方案:解决方案一:更新CA证书下载最新的CA证书访问 curl官方提供的CA证书 页面下载 cacert.pem 文件。上传证书文件将下载的 cacert.......