• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
24
博客园    首页    新随笔    联系   管理    订阅  订阅

cf

10.31

Divisibility by Eight(1500)

题目大意:
给你一个不包含前导0的整数,位数100位,问是否可以在通过删除一些位数,且不能改变原有位置的情况下整除8?

解题思路:
我们可以发现1000正好是8的倍数,所以我们只需要枚举是否存在1位数,2位数,3位数可以整除8即可,至于为什么不用枚举4位数及更高的位数呢?我们来分析一下,对于任意一个4位数及更高位数的整数 x 都可以表示为 x = 1000 * n + k 的形式,而1000是8的倍数,那么自然1000 * n 也是8的倍数,所以我们可以通过判断k是否能整除8进而来判断x是否能整除8,又因为k可能是1位数,2位数,3位数,所以正好可以应证前面的结论。

 

#include<bits/stdc++.h>
using namespace std;
string s;

int main(){
    cin>>s;
    for(int i=0;i<s.size();i++){
        if((s[i]-'0')%8==0){
            cout<<"YES"<<endl;
            cout<<s[i]<<endl;
            return 0;
        }
    }
    for(int i=0;i<s.size();i++){
        for(int j=i+1;j<s.size();j++){
            if(((s[i]-'0')*10+(s[j]-'0'))%8==0){
                cout<<"YES"<<endl;
                cout<<s[i]<<s[j]<<endl;
                return 0;
            }
        }
    }
    for(int i=0;i<s.size();i++){
        for(int j=i+1;j<s.size();j++){
            for(int k=j+1;k<s.size();k++){
                if(((s[i]-'0')*100+(s[j]-'0')*10+s[k]-'0')%8==0){
                    cout<<"YES"<<endl;
                    cout<<s[i]<<s[j]<<s[k]<<endl;
                    return 0;
                }
            }
        }
    }
    cout<<"NO"<<endl;
    return 0;
}


Gift Set(2100)

题意

 


有x个红糖,y个蓝糖。每一个礼包里面要么有a个红糖+ b个蓝糖,要么是a个蓝糖+ b个红糖。
问最多能打多少份礼包。
T ≤104组数据,1 ≤x, y,a, b ≤10°。


题解


不难发现答案具有包含性,能打n份就─定能打n —1份。
交换,令a >b,那么每打包一份礼包,x和y都至少会减少b。
直接二分答案s,那么在x, y ≥S · b的前提下,再把x和y都减去s · b后,相当于在x, y中只用找单独的s个ab就行了({x. y}变成了{x - sb, y - sb}, {a, b}变成了{a - b, 0},其中一个为0了,两种糖果不再绑定),这等价于此时a = b或者 x/(a-b) + y/(a-b) >= s

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
ll x,y,a,b;

bool check(ll k){
    ll X=x,Y=y,A=a,B=b;
    if(X<k*B||Y<k*B) return false;
    X-=k*B,Y-=k*B;
    A=A-B;
    if(A==0) return true;
    return X/A+Y/A>=k;
}

void solve(){
    cin>>x>>y>>a>>b;
    if(x<y)swap(x,y);
    if(a<b)swap(a,b);
    ll l=0,r=1e9+10;
    for(int i=1;i<=200;i++){
        ll mid=(l+r)>>1;
        if(check(mid)) l=mid;
        else r=mid;
    }
    cout<<l<<endl;
}

int main(){
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

 

11.2

Magic Stones(2200)

格里戈里有n块魔法石,方便地从1到n编号。第i块魔法石的电荷等于ci。

有时Grigory会感到无聊,并选择一些内部石头(即,一些索引为i的石头,其中2≤我≤n−1) ,然后将其与相邻的石头同步。之后,被选中的石头失去了自己的电荷,但从相邻的石头获得了电荷。换句话说,它的电荷ci变为c′i=ci+1+ci−1.−ci。

格里戈里的朋友安德鲁也有n块石头,其电荷为ti。格里戈里很好奇,是否存在一系列零或更多的同步操作,将格里戈里石头的电荷转换为相应的安德鲁石头的电荷,也就是说,将所有i的ci变为ti?

 

输入

第一行包含一个整数n(2≤n≤105)-魔法石的数量。

第二行包含整数c1、c2、…、cn(0≤ci公司≤2.⋅109)-格里戈里石头的指控。

第二行包含整数t1、t2、…、tn(0≤钛≤2.⋅109)-指控安德鲁的石头。

 

输出

如果存在同步操作序列(可能为空),将所有费用更改为所需费用,请打印“是”。

否则,打印“否”。

 

考虑差分,发现题目中的变换,到差分数组中就相当于相邻两位的交换,所以只需比较两个差分数组是否一致即可

#include<bits/stdc++.h>
using namespace std;
int n,a[200005],b[200005],c[200005],d[200005];

int main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int j=1;j<=n;j++) cin>>b[j];
	if(a[1]!=b[1]){
		cout<<"NO"; return 0;
	}
	for(int i=1;i<=n;i++) c[i]=a[i]-a[i-1],d[i]=b[i]-b[i-1];
	sort(c+2,c+n+1);
	sort(d+2,d+n+1);
	for(int i=2;i<=n;i++){
		if(c[i]!=d[i]){
			cout<<"NO";
			return 0;
		}
	}
	cout<<"YES";
	return 0;
}

 

posted @ 2022-10-31 00:57  wxk1213  阅读(118)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3