A
題意:A,B,C三個人分別有硬幣a,b,c枚,D有n枚硬幣要全部分給A,B,C三人,問是否存在分配方案使最終A,B,C三人硬幣數相等。
我的思路:算出每人距離三人中的最大值 差多少,先從n裏面拿一些硬幣把這個差距補平,然後看剩下的硬幣數能不能整除3。
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin>>t;
while(t--){
int a,b,c,n;
cin>>a>>b>>c>>n;
int maxn=max({a,b,c});
int p=maxn-a+maxn-b+maxn-c;
if(p<=n&&(n-p)%3==0) puts("YES");
else puts("NO");
}
}
B
題意:給出n個包裹的位置(x,y),機器人從(0,0)出發,只能向右或向上,問是否存在一種走法能訪問到所有的包裹,向右是'R',向上是'U',輸出字典序最小的走法。
我的分析:對n個包裹排序(以x爲第一關鍵字,y爲第二關鍵字(這樣其實用pair就可以)),這樣如果某個排在前面的包裹,卻在後面的包裹的右下方(應該在右上),就是沒法走的情況,flag=false。
#include<bits/stdc++.h>
using namespace std;
const int N=1005;
struct node{
int x,y;
bool operator < (const node& t)const{
if(x==t.x) return y<t.y;
return x<t.x;
}
}a[N];
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
char ans[2005];
int cnt=0;
for(int i=1;i<=n;++i) cin>>a[i].x>>a[i].y;
sort(a+1,a+1+n);
bool flag=true;
for(int i=1;i<=n;++i){
if(a[i].y<a[i-1].y) {flag=false;break;}
else{
for(int j=0;j<a[i].x-a[i-1].x;++j) ans[cnt++]='R';
for(int j=0;j<a[i].y-a[i-1].y;++j) ans[cnt++]='U';
}
}
if(flag){
puts("YES");
ans[cnt]=0;
puts(ans);
}else{
puts("NO");
}
}
}
注意:char ans[cnt]=0,纔可cout<<ans;否則會輸出奇怪的字符。
C.
題意:給出n,問n能否拆成三個不同的數a,b,c的乘積,a,b,c>2,可以的話輸出a,b,c.
我的思路:對n分解質因數,如果某個質因數的個數到達6(比如6個2)或者能分解出3個不同的質因數或者能分解出兩個不同的質因數且這兩個質因數的總個數到達4,那麼yes,否則no。
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
while (n--){
int x;
cin >> x;
int cnt=0;
int xx=x;
bool flag=false;
int a[105],b[105];
memset(a,0,sizeof a);
memset(b,0,sizeof b);
for (int i = 2; i <= x / i &&!flag; i ++ )
if (x % i == 0){
++cnt;
int s = 0;
while (x % i == 0) x /= i, s ++ ;
a[cnt]=i;
b[cnt]=s;
if(cnt>=3||b[cnt]>=6||cnt>=2&&b[cnt]+b[cnt-1]>=4){
flag=true;
break;
}
}
if(x>1) {++cnt;a[cnt]=x;b[cnt]=1;}
if(cnt>=3||b[cnt]>=6||cnt>=2&&b[cnt]+b[cnt-1]>=4){flag=true;}
if(flag){
puts("YES");
if(b[cnt]>=6) cout<<a[cnt]<<" "<<a[cnt]*a[cnt]<<" "<<xx/(a[cnt]*a[cnt]*a[cnt])<<endl;
else cout<<a[cnt]<<" "<<a[cnt-1]<<" "<<xx/(a[cnt]*a[cnt-1])<<endl;
}else{
puts("NO");
}
}
return 0;
}
//思路秒出,實現浪費了很多時間
D.初始數組爲空,給出n和k,有n次詢問,每次給出a_i,加(append)在數組裏,每次加完數後,可以進行這樣的操作:對當前數組中任意的數加上或減去任意次k,使該數組的MEX(最小非負整數)最大,輸出這個最大的MEX,在下一次詢問前,所有操作清空。
思路:可以發現每次的答案是單調遞增的,然後模擬。。。我暫時講不清楚
#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
int a[N];
int main(){
int n,k;
scanf("%d%d",&n,&k);
int now=0;
while(n--){
int x;
scanf("%d",&x);
++a[x%k];
while(a[now%k]){
--a[now%k];
++now;
}
printf("%d\n",now);
}
return 0;
}