A - Gold and Silver
题目链接:https://atcoder.jp/contests/arc128/tasks/arc128_a
Input
Input is given from Standard Input in the following format:
N
A1 A2 ... AN
Output
Print the answer in the following format:
v1 v2 ... vN
Sample Input 1
3
3 5 2
Sample Output 1
0 1 1
The optimal sequence of actions is as follows.
Day 1: Do nothing.
Day 2: Exchange 1 gram of gold for 5 grams of silver.
Day 3: Exchange 5 grams of silver for 2.5 grams of gold.
Sample Input 2
4
1 1 1 1
Sample Output 2
0 0 0 0
(v1,v2,v3,v4)=(1,1,1,1), for example, is also considered correct.
Sample Input 3
10
426877385 186049196 624834740 836880476 19698398 709113743 436942115 436942115 436942115 503843678
Sample Output 3
1 1 0 1 1 1 1 0 0 0
code:
#include <iostream>
#include <algorithm>
using namespace std;
const int N=2e5+5;
int a[N],ans[N];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
for(int i=1;i<=n-1;i++)
{
if(a[i]>a[i+1])
{
ans[i]++;
ans[i+1]++;
}
}
cout<<ans[1]%2;
for(int i=2;i<=n;i++) cout<<" "<<ans[i]%2;
//cout<<"\n";
return 0;
}
这道题是个思维题,不得不说做法很巧妙。这道题的正确解法是:我们在遍历数组时,判断当前的值a[i]是否大于下一个值a[i+1],如果是,答案就是a[i]/a[i+1],ans[i]=1,ans[i+1]=0,不过这就有问题了,如果a[i]>a[i+1]>a[i+2]>a[i+3]怎么办呢,答案是a[i]/a[i+3],ans[i]=ans[i+3]=1,ans[i+1]=ans[i+2]=0,这就有人问了,为啥不是(a[i]*a[i+2])/(a[i+1]*a[i+3])呢?其实做题时多选取几个例子就会发现a[i]/a[i+3]更大。这里就不做证明了。为啥我说做法巧妙呢?细品:
for(int i=1;i<=n-1;i++)
{
if(a[i]>a[i+1])
{
ans[i]++;
ans[i+1]++;
}
}
输出时:
cout<<ans[1]%2;
for(int i=2;i<=n;i++) cout<<" "<<ans[i]%2;
这种做法就巧妙地解决了这个标记的问题,不然的话我们在遍历时要做很多功夫来标记目标位置,更新位置,这就很麻烦了,而这种做法就化繁为简,看完后让人惊叹:原来还可以这样做!
B - Balls of Three Colors
题目链接:https://atcoder.jp/contests/arc128/tasks/arc128_b
Input
Input is given from Standard Input in the following format:
T
case1
case2
.
.
.
caseT
Each case is in the following format:
R G B
Output
For each case, print -1 if the objective is unachievable; otherwise, print the minimum number of operations to achieve it.
Sample Input 1
3
1 2 2
1 2 3
1 2 4
Sample Output 1
2
-1
4
For example, in case3, one optimal sequence of operations is:
choose a green ball and blue ball, turning them into two red balls;
choose a red ball and blue ball, turning them into two green balls;
choose a red ball and blue ball, turning them into two green balls;
choose a red ball and blue ball, turning them into two green balls.
code:
#include<bits/stdc++.h>
using namespace std;
int T,R,G,B;
int calc(int x,int y){
if(x%3!=y%3)return 1e9;
return max(x,y);
}
int main(){
cin>>T;
while(T--){
cin>>R>>G>>B;
int a=calc(G,B);
int b=calc(R,B);
int c=calc(R,G);
int minn=min(min(a,b),c);
cout<<(minn==1e9?-1:minn)<<endl;
}
return 0;
}
这道题也是个思维题,我们可以拿样例举例,比如输入是1,2,4的情况,题目里面也做了具体解释,根据这个解释我们会发现答案其实就是第三个也就是蓝色小球的数量,在算的过程中4减了1,2减了1,1加了2,也就变成3,1,3,之后就是两个3来减1,中间的1加2了,一直到3为0,这时你有没有发现:只要能减到有两个数相同的情况就会有答案,而且答案数还是固定的,就等于max(a,b),a,b分别为减1的数和加2的数,且这个减1的数是能减到与加2的数相等的,因为只有三种颜色的小球,所以我们可以计算3次:calc(R,G),calc(R,B),calc(G,B),如果存在相同的情况则calc的返回值是两个数中的较大值,否则返回1e9,之后我们就取三次计算的最小值,判断最小值是否为1e9,如果是则返回-1,否则返回就返回那个最小值。这里在判断是否有相同情况时用了对3取模的运算:
int calc(int x,int y){
if(x%3!=y%3)return 1e9;
return max(x,y);
}
我们在算的时候会发现那两个数的差值一直在减3,直到他们相等,于是我们就可以直接将两个数对3取模就能判断出来了,这个方法值得我们借鉴。