第一题:Login - Codeforces
题目大意:
给定一个温度范围 [l,r] 以及参数 x ,给定初始温度a和目标温度b,求最少次数将初始温度a变为目标温度b的操作数,每次切换温度必须保证温度变化大小大于等于x。
解题思路:
(贪心!!!)
显然只有五种可能的答案:0、-1、1、2、3。
即要么无需操作,要么无解,要么最多只需要三步。
当a == b时,输出0;
if(abs(a-b)>=x)只需要一步输出1;
两步:先向l或者r方向移动,然后反向移动到b。
三步:先向r/l方向移动,然后再向l/r方向移动,再移动到b。
操作的前提是移动的时候不超过l和r。所以判断a、b和l、r之间的差值即可。
(其实这题很简单,当时没写出来是真没有想到只有0、-1、1、2、3这五种可能,还以为会有其他更多方案的操作数,所以就没有想出来)
题解:
#include<bits/stdc++.h>
using namespace std;
int l,r,x,a,b;
void solve(){
cin>>l>>r>>x>>a>>b;
if (a==b){
cout<<0<<endl;
return;
}
if (abs(a-b)>=x){
cout<<1<<endl;
return;
}
else{
if (a<b){
if (a-l>=x){cout<<2<<endl;return;}
if (r-b>=x){cout<<2<<endl;return;}
if (r-b<x&&a-l<x&&r-a>=x&&b-l>=x){cout<<3<<endl;return;}
}
else if (a>b){
if (b-l>=x){cout<<2<<endl;return;}
if (r-a>=x){cout<<2<<endl;return;}
if (r-a<x&&b-l<x&&a-l>=x&&r-b>=x){cout<<3<<endl;return;}
}
}
cout<<-1<<endl;
}
int main()
{
int t;
cin>>t;
while (t--){
solve();
}
return 0;
}
第二题:Login - Codeforces
题意:给定一个n和m,k的取值范围在1~m,求出最大的n*k并满足有最多的末尾0。
思路:首先10 = 2*5,所以要使末尾有0,首先必须出现2和5,所以我们先分解n,看一下n有多少个5,多少个2,假设n分解之后有4个2,1个5,它本身1个2和1个5相乘等于10,所以剩下3个2,那么此时,k就先补3个5,既5*5*5 = 125,如果此时k还没有超出范围的话,就继续乘10,如果乘10后超出范围了,就在1~9之间相乘,找到最大的那个k。如果k在补5的时候超出范围了,比如m = 26,我们就不能5*5*5了,只需要k = 5*5 = 25即可
///代码题解一
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,k;
//要使由多个0则可使2*5=10就会有一个0,就看两个数能由多少个2*5的组合组成
void solve(){
cin>>n>>m;
ll a=n;
int cnt2=0,cnt5=0;
while(a%2==0){//计算n可由多少个2组成
cnt2++;
a/=2;
}
a=n;
while(a%5==0){//计算n可由多少个5组成
cnt5++;
a/=5;
}
k=1;
while(cnt2>cnt5&&k*5<=m&&cnt2--) k*=5;//将5与2配对,更新k;
while(cnt2<cnt5&&k*2<=m&&cnt5--) k*=2;//将2与5配对,更新k;
while(k*10<=m){//若配对完还能凑出10就继续更新k;
k*=10;
}
cout<<m/k*k*n<<endl;
}
int main()
{
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
int t=1;
cin>>t;
while (t--){
solve();
}
return 0;
}
/代码题解二
#include<bits/stdc++.h>
#include<iostream>
#include<cmath>
typedef long long ll;
using namespace std;
const int N = 2e5+10;
const int mod = 1e9+7;
ll a[N],b[N],c[N];
void solve(){
ll n,m;
cin >> n >> m;
ll k=1;
int c2=0,c5=0;
ll nn = n;
while(nn%2==0)
{
c2++;
nn/=2;
}
nn=n;
while(nn%5==0)
{
c5++;
nn/=5;
}
int d = abs(c2-c5);
if(c2>c5)
{
while(d--&&k*5<=m)
{
k*=5;
}
}
else
{
while(d--&&k*2<=m)
{
k*=2;
}
}
while(k*10<=m)
{
k*=10;
}
for(int i=1;i<=10;i++)
{
if(k*i>m)
{
k*=(i-1);
break;
}
}
cout << n*m/k*k << endl;
}
int main()
{
int t=1;
cin >> t;
while(t--) solve();
return 0;
}
第三题:Login - Codeforces
题面:
题意:给你一定数量的a,b。两个a+1个b或者1个a+2个b 都可以合成一个宝石,问最多合成多少个宝石
思路:特判a==0||b==0的时候生成0个宝石;当a或b两倍的数量比b或a少,则最多能生成a或b个宝石;当a!=b的时候,a-2*n=b-n推出n=a-b;
(当时没写出来是因为没太弄懂各种情况!
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a,b;
int ans,num;
void solve(){
cin>>a>>b;
ans=0;
if (a==0||b==0){cout<<0<<endl;return;}
if (a*2<=b) {cout<<a<<endl;return;}
if (b*2<=a) {cout<<b<<endl;return;}
if (a!=b){//当a!=b时
if (a>b){
num=a-b;
ans+=num;
a-=num*2;
b-=num;
}
if (a<b){
num=b-a;
ans+=num;
b-=num*2;
a-=num;
}
}
///此时a==b;
num=a/3;
ans+=num*2;
a%=3,b%=3;
if (a>1&&b>0||b>1&&a>0){
ans+=1;
}
cout<<ans<<endl;
}
int main()
{
ios::sync_with_stdio(false);
int t=1;
cin>>t;
while(t--)solve();
return 0;
}
第四题:Login - Codeforces
题面:
题意:是否可以将一个串,分成至少两个部分,使得前一个部分的数字大小小于后面的。
思路:就是一个水题,只要将其分成两部分即可,(没写出来因为没看懂题目(;´༎ຶД༎ຶ`)
题解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void solve(){
int n;
string s;
cin >> n >> s;
if(n==2 && s[0]>=s[1] ){//特判当n=2的时候,如果前一个比后一个大则不能
cout<<"NO"<<endl;
}
else{
cout<<"YES"<<endl;
cout<<"2"<<endl<<s[0]<<" "<< s.substr(1, s.size())<<endl;
}
}
int main()
{
ios::sync_with_stdio(false);
int t=1;
cin>>t;
while(t--)solve();
return 0;
}
第五题:
题面:
题意:定义一个数组a[x]=1,其余数组都为0,每次给定m个区间,在这个区间内的任何两个数可以进行交换,问操作m次以后区间里面最多有多少个可以等于1。
题解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e9+10;
int n,m,x;
int l,r;
void solve(){
cin>>n>>x>>m;
l=x,r=x;
int a,b;
for (int i = 1; i <= m; ++i) {
cin>>a>>b;
if (b<l||a>r){continue;}
l=min(l,a);
r=max(r,b);
}
cout<<r-l+1<<endl;
}
int main()
{
ios::sync_with_stdio(false);
int t=1;
cin>>t;
while(t--)solve();
return 0;
}