首页 > 其他分享 >AtCoder Beginner Contest 332 题解

AtCoder Beginner Contest 332 题解

时间:2023-12-12 22:55:24浏览次数:49  
标签:std AtCoder 衣服 马克杯 int 题解 long 332 徽标

A - Online Shopping

题目链接

Atcoder

Luogu

简要题意

共有 \(n\) 件商品,第 \(i\) 件商品的价格为 \(p_i\) 日元,数量为 \(q_i\) 件。

除了购买商品所需的的钱数,还要支付运费:如果所买商品的总价小于 \(s\) 日元,那么要支付运费 \(k\) 日元。

问所需要的钱数是多少。

简要思路

模拟即可。

完整代码

#include<bits/stdc++.h>
#define int long long
#define endl '\n'

int n,s,k;
int p,q;
int ans;

signed main(){
	std::cin>>n>>s>>k;
	for(int i=1;i<=n;i++){
		std::cin>>p>>q;
		ans+=p*q;
	}
	if(ans<s)ans+=k;//有运费
	std::cout<<ans<<endl;
	return 0;
}

B - Glass and Mug

题目链接

Atcoder

Luogu

简要题意

有一个容量为 \(g\) 的玻璃杯和一个容量为 \(m\) 的马克杯,你要进行 \(k\) 次以下操作:

  • 如果玻璃杯中装满了水,那么将玻璃杯中的水倒掉;

  • 如果马克杯是空的,就将马克杯中注满水;

  • 否则将马克杯中的水注入到玻璃杯中,直至玻璃杯中水满了或者马克杯中没有水了。

最后数组玻璃杯和马克杯中剩余的水。

简要题意

按照题意模拟。

定义两个数分别用来记录当前玻璃杯和马克杯中剩余的水。

对于第三个操作,我们可以简便操作为对当前玻璃杯还能注入的水的毫升数和马克杯中剩余的水的毫升数取 min,注意提前维护一个值防止其值发生改变。

完整代码

#include<bits/stdc++.h>
#define int long long
#define endl '\n'

int k,g,m;
int glass,mug;//玻璃杯和马克杯当前杯中的水的毫升数

signed main(){
    std::cin>>k>>g>>m;
    for(int i=1;i<=k;i++){
    	if(glass==g)glass=0;//玻璃杯内装满了水
    	else if(mug==0)mug=m;//马克杯是空的
    	else {
    		int now=glass;//提前记录原先玻璃杯中的水
    		glass+=std::min(mug,g-glass);
			mug-=std::min(mug,g-now);//从马克杯往玻璃杯中倒
		}
	}
	std::cout<<glass<<' '<<mug<<endl;
	return 0;
}

C - T-shirts

题目链接

Atcoder

Luogu

简要题意

高桥公司有一个 \(n\) 天的行程 \(s\),在初始时,他们有 \(m\) 件普通衣服。

每天的活动情况为:

如果 \(s_i\) 为 0,那么这一天没有任何安排,可以将之前所有的普通衣服和徽标衣服洗干净;

如果 \(s_i\) 为 1,那么这一天要身穿普通或徽标衣服;

如果 \(s_i\) 为 2,那么这一天要身穿徽标衣服。

注:每件普通衣服和徽标衣服在洗干净之前只能穿一天。

问至少要买多少件衣服才能使每天都有衣服穿。

简要思路

二分答案,寻找最小的购买的衣服数量。

因为徽标衣服是相对“万能”的,所以我们只需二分徽标衣服的数量。

check 判断中,如果能穿普通衣服就先穿普通衣服,否则穿徽标衣服。

完整代码

#include<bits/stdc++.h>
#define int long long
#define endl '\n'

int n,m;
char s[1005];

bool check(int x){
	int num1=m;//普通衣服的数量
	int num2=x;//徽标衣服的数量
	for(int i=1;i<=n;i++){
		if(s[i]=='0'){//无安排
			num1=m;
			num2=x;//将前面所有穿过的衣服洗干净
		}else if(s[i]=='1'){
			if(num1>0)num1--;//能穿普通衣服先穿普通衣服
			else{
				if(num2>0)num2--;
				else return false;
			}
		}else{
			if(num2>0)num2--;//只能穿徽标衣服
			else return false;
		}
	}
	return true;
}

signed main(){
	std::cin>>n>>m>>s+1;
	
	int l=0,r=1000;
	while(l<=r){//二分答案
		int mid=(l+r)>>1;
		if(check(mid))r=mid-1;
		else l=mid+1;
	}
	std::cout<<r+1<<endl;
	return 0;
}

D - Swapping Puzzle

题目链接

Atcoder

Luogu

简要题意

给定两个 \(h \times w\) 的矩阵 \(A,B\),每次操作可以交换矩阵 \(A\) 中相邻两行的所有元素或相邻两列的所有元素。

求至少需要多少次操作才能使 \(A\) 矩阵变化为 \(B\) 矩阵,如果不能实现输出 -1

简要思路

首先注意到:\(2 \leq H, W \leq 5\),因此我们可以大胆猜测这是一个很暴力的做法,不难想到全排列,接下来来详细说明一下做法。

用数组 \(h\) 记录当前矩阵的第 \(i\) 排对应原先 \(A\) 矩阵中的第 \(h_i\) 排。

用数组 \(w\) 记录当前矩阵的第 \(i\) 列对应原先 \(A\) 矩阵中的第 \(w_i\) 列。

全排列枚举每一种交换矩阵的形式,如果符合条件我们就统计当前 \(h,w\) 数组中逆序对的数量,并和当前答案取最小值。

注:对于一个 \(1\) 到 \(n\) 每个数只出现一次的序列,如果想让它变成升序排列,那么至少要进行调换的次数为这个序列的逆序对的数量。

对于不存在答案的情况,我们只需刚开始时对答案赋一个极大的值,最后判断是否等于该值即可。

完整代码

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
const int INF=1e9+5;

int H,W;
int a[10][10],b[10][10];//a,b 矩阵
int h[10],w[10];//枚举全排列所用数组

signed main(){
	std::cin>>H>>W;
	for(int i=1;i<=H;i++)
		for(int j=1;j<=W;j++)std::cin>>a[i][j];
	for(int i=1;i<=H;i++)
		for(int j=1;j<=W;j++)std::cin>>b[i][j];
  	
  	for(int i=1;i<=H;i++)h[i]=i;
  	for(int j=1;j<=W;j++)w[j]=j;//初始赋值,注意从小到大
  	
  	int ans=INF;//赋初始较大值
  	do{
  	  	do{
			bool f=true;
			for(int i=1;i<=H;i++)
				for(int j=1;j<=W;j++)
					if(a[h[i]][w[j]]!=b[i][j]){
						f=false;
						break;
					}
   	  		if(f==false)continue;//判断当前矩阵是否等于 b 矩阵

      		int num=0;
      		for(int i=1;i<=H;i++)
				for(int j=1;j<=H;j++)
					if(i<j&&h[i]>h[j])num++;
			for(int i=1;i<=W;i++)
				for(int j=1;j<=W;j++)
					if(i<j&&w[i]>w[j])num++;//交换次数=两个数组的逆序对数量之和
      		ans=std::min(ans,num);//维护答案

    	}while(std::next_permutation(w+1,w+W+1));
  	}while(std::next_permutation(h+1,h+H+1));//全排列枚举每一种交换情况

  	if(ans==INF)std::cout<<-1<<endl;//答案没有变说明不存在答案
  	else std::cout<<ans<<endl;

  	return 0;
}

标签:std,AtCoder,衣服,马克杯,int,题解,long,332,徽标
From: https://www.cnblogs.com/CheZiHe929/p/17898056.html

相关文章

  • AtCoder Beginner Contest 332
    AtCoderBeginnerContest332A-OnlineShopping代码:#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=1e6+10;typedefpair<ll,ll>pii;voidsolve(){intn,s,k;cin>>n>>s>>......
  • AtCoder Grand Contest 001
    比赛链接A-BBQEasy从小到大排序以后,答案就是所有奇数位置之和。B-MysteriousLight发现去掉前两次反射以后,剩下的是一个在平行四边形内反射的过程,且形式类似于辗转相除。具体地,\[F(n,x)=\begin{cases} -n&x=0\\ 2x\lfloor\frac{n}{x}\rfloor+F(x,n\bmodx)&x>0\e......
  • cdr 小问题解决方案
    1,插件卸载不干净1.1:插件自带的卸载1.2:点击cdr文件夹,选择路径CorelDRAWGraphicsSuiteX8\Draw\plugins64,删除其中所有的"*.cpg"文件(如果你安装了其他插件,这里也会有其他插件的cpg文件,请仔细辨认。或者直接全部删了,到时再安装一下你需要保留的插件)。 2,cdr矩形,对象属性无法更......
  • 【POJ 2418】Hardwood Species 题解(映射)
    描述阔叶树是一种植物群,具有宽阔的叶子,结出果实或坚果,通常在冬天休眠。美国的温带气候造就了数百种阔叶树种的森林,这些树种具有某些生物特征。例如,虽然橡树、枫树和樱桃都是硬木树,但它们是不同的物种。所有硬木树种加起来占美国树木的40%。另一方面,软木,或针叶树,从拉丁语的意思是......
  • AtCoder Regular Contest 169
    A-PleaseSign某个\(A_i\)对\(A_1\)的贡献是\(\binom{10^{100}}{\mathrm{dep}_i}\),所以深度为\(d\)的节点的\(A_i\)之和只要不为\(0\),其贡献就一定远大于深度\(<d\)的所有点的贡献之和。从大到小找到第一个和非零的深度即可。B-SubsegmentswithSmallSums直......
  • ABC332G
    题面有\(n\)种颜色的球,第\(i\)种颜色的球有\(a_i\)个,有\(m\)个盒子,第\(i\)个盒子能装\(b_i\)个球,第\(i\)个颜色的球在第\(j\)个盒子中最多装\(ij\)个,求最多能装多少个球。\(n\le500,m\le5\times10^5a_i,b_i\le10^{13}\)。题解要注意到这是个网络流模......
  • luogu P9753题解
    题意描述有一个字符串,请你求出有多少个字串可以经过若干次,使它变成空串其中每次操作可以从字符串中删除两个相邻的相同字符,操作后剩余字符串会拼接在一起。##思路1可以枚举左端点,再枚举右端点,一边枚举一边判断是否合法时间复杂度$O(n^2)$空间复杂度$O(n)$##思......
  • ARC166 B Make Multiples 题解
    LinkARC166BMakeMultiplesQuestion给出\(N\)个整数,\(A_1...A_N\),还有三个数\(a,b,c\)我们可以给\(A_i\)加上\(1\)需要使得数组\(A\)满足,存在一个数是\(a\)的倍数,一个数是\(b\)的倍数,一个数是\(c\)的倍数求最少的操作次数Solution考虑对于每个数的操作......
  • CF1901 D Yet Another Monster Fight 题解
    LinkCF1901DYetAnotherMonsterFightQuestion现在给你一堆怪物,你拥有法术(一个法术可以连续攻击这n个所有怪物),你可以选择任意一个怪物作为法术的第一个攻击目标(伤害为\(x\)),然后除了第一个攻击目标可以任意,其他攻击目标只能为曾经攻击目标的相邻怪物。然后伤害依次递减,\(x......
  • CF1764H Doremy's Paint 2 题解
    题目链接先断环成链,由于对于多组询问不好一起处理,我们先考虑单组询问的处理方式。一个很暴力的想法是每次模拟题目要求的操作并且最后数颜色,我们这是在通过下标进行操作最后再数颜色,而很多对于下标的操作都是不必要的,考虑直接枚举颜色进行判定。对于每种颜色,它对于最后答案有贡......