(https://ac.nowcoder.com/acm/contest/95016#question)(比赛链接)
目录
A.排序危机
1.思路
遍历三次字符串,依次输出小写字母、数字、大写字母(输出数字的时候少了0卡了半天。。)
2.代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
int n;
cin>>n;
string s;
cin>>s;
string re = "";
for(int i=0;i<n;i++){
if(s[i]>='a'&&s[i]<='z'){
re+=s[i];
}
}
for(int i=0;i<n;i++){
if((s[i]-'0')>=1&&(s[i]-'0')<=9){
re+=s[i];
}
}
for(int i=0;i<n;i++){
if(s[i]>='A'&&s[i]<='Z'){
re+=s[i];
}
}
cout<<re<<endl;
return 0;
}
B.小歪商店故事:卷
1.思路
直接利用c*b/d算amax,再乘回去是否能等于c*b,能的话说明re正好等于amax,需要对re-1,否则算出来的re是已经去除小数部分的数值,就是amax,无需更改,输出a-re就行
2.代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
int a,b,c,d;
cin>>a>>b>>c>>d;
int re = (c*b)/d;
if((re*d)==(c*b)){
re-=1;
}
cout<<a-re<<" ";
}
signed main(){
int n;
cin>>n;
while(n--){
solve();
}
cout<<endl;
}
C.小苯的计算式
1.思路
暴力枚举即可,直接枚举从0到C的所有情况,前提是保证整个式子的长度和为n
2.代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
signed main(){
int n;
string s;
cin>>n>>s;
int c = stoi(s);
int len = s.length();
int yu = n-2-len;
int sum = 0;
for(int i=0;i<=c;i++){
int t = c-i;
int len1 = to_string(i).length();
int len2 = to_string(t).length();
if(len1+len2==yu){
sum+=1;
}
}
cout<<sum<<endl;
return 0;
}
D.K
1.思路
极大不同区间的最大宽度为1,所以k的最大值只能是n,因此当k>n的时候一定构造不出来。这题观察示例1可以发现通过不断重复元素的方式来保证区间长度不变的情况下,不断增加极大不同区间的个数。如145,后重复1,既保证了区间长度为3,即451,又使得个数增加。451后重复4,保证区间长度为3,即514,又使得个数增加。多个例子探讨发现这种规律是可行的,但要如何构造初始区间呢。即145还有初始区间的个数,还是通过找规律发现,初始构造区间的个数为n-k+1,且初始区间递增也满足上述的要求,此后不断重复输出初始区间即可,直到输出n个数
// 6 2
// 1 2 3 4 5 1
// 6 3
// 1 2 3 4 1 2
// 6 4
// 1 2 3 1 2 3
// 6 5
// 1 2 1 2 1 2
2.代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+7;
int a[N];
signed main(){
int n,k;
cin>>n>>k;
if(k>n){
cout<<"NO"<<endl;
return 0;
}
cout<<"YES"<<endl;
int t = n-k+1;
for(int i=1;i<=t;i++){
a[i] = i;
cout<<i<<" ";
}
int yu = n-t;
int index = 1;
for(int i=1;i<=yu;i++){
cout<<a[index]<<" ";
index++;
if(index==t+1){
index=1;
}
}
return 0;
}
// 6 2
// 1 2 3 4 5 1
// 6 3
// 1 2 3 4 1 2
// 6 4
// 1 2 3 1 2 3
// 6 5
// 1 2 1 2 1 2
E.小苯的区间选数
1.思路
题目中选取两个数求和可以转化为从区间 [l1+l2,r1+r2] 选取一个数使得数位和最大。如何使得数位和最大,就是尽量让9的个数多,比如2134,我们选择将2-1,然后使后面所有数变为9,即1999。首先设置结果为左右区间的数位和取较大值,接下来探讨两种情况。
当左右区间的长度相同的时候,对两个区间的对应位置的数值进行比较,比如:1234和1267,r[i] > l[i] 的时候才选择将i-1,否则会使得右区间小于左区间,不符合要求。
当左右区间长度不相同的时候,直接对右区间第一个数-1,然后后面所有变9即可。有一种情况就是右区间为999999,按如上操作反而导致数位和变小,所有这就是为什么我们刚开始初始化的时候,设置结果为左右区间的数位和取较大值
2.代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
void solve(){
int l1,r1,l2,r2;
cin>>l1>>r1>>l2>>r2;
string l = to_string(l1+l2);
string r = to_string(r1+r2);
int ans = 0,anx = 0;
for(int i=0;i<r.length();i++){
ans += r[i]-'0';
}
for(int i=0;i<l.length();i++){
anx += l[i]-'0';
}
int re = max(ans, anx);
// cout<<"left:"<<l<<" "<<"right:"<<r<<" "<<re<<endl;
if(r.length()>l.length()){
int t = (r[0]-'0'-1)+(9*(r.length()-1));
re = max(re,t);
}else{
int i = 0;
int sum = 0;
for(i;i<r.length();i++){
if(l[i]>=r[i]){
sum += r[i]-'0';
}else{
break;
}
}
sum += r[i]-'0'-1;
sum += (r.length()-i-1)*9;
re = max(re,sum);
}
cout<<re<<endl;
}
signed main(){
int t;
cin>>t;
while(t--){
solve();
}
}