蓝桥杯模拟赛2

A题 解码

题意:一个字符串,有数字和字母组成,有一种简写方式H5为HHHHH,让你输出解码后的字符串.

思路:遍历字符串,没遇到数字就输出,遇到数字就把前面的字符输出这个数字减一次,因为前面的字符已经输出过一次了。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=10010;
typedef long long ll;
pair<char,int> p[110];
int main() {
    IOS;
    string s1,s2;
    int t=0;
    cin>>s1;
    for(int i=0;i<s1.size();i++){
        if(s1[i]>='0'&&s1[i]<='9'){
            for(int j=0;j<s1[i]-'0'-1;j++){
                cout<<s1[i-1];
            }
        }
        else cout<<s1[i];
    }
    return 0;
}

B题 成绩分析

题意:统计最高分,最低分和平均分.

思路:存到数组里排序并计算总和合,输出第一个和最后一个,计算平均分即可。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=10010;
typedef long long ll;
pair<char,int> p[110];
int main() {
    IOS;
    int n,sum=0;
    int a[n+10];
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>a[i];
        sum+=a[i];
    }
    sort(a,a+n,greater<int>());
    printf("%d\n%d\n%.2f\n",a[0],a[n-1],sum*1.0/n);
    return 0;
}

C题 整数序列

题意:一个数n,每次除以2,输出除以2并且除以之后大于零的数,空格隔开。

思路:用一个while循环,当n<=0时结束即可,但是要特别注意数据范围时long long

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=10010;
typedef long long ll;
pair<char,int> p[110];
int main() {
    IOS;
    ll n;
    cin >> n;
    while (n > 0) {
        cout << n << ' ';
        n /= 2;
    }
    return 0;
}

D题 日期识别

题意:一个由月份英文缩写和日数字组成的字符串,把他转化成数字日期。

思路:先定义一个月份英文缩写的数组,截取字符串的英文缩写,遍历数组,找出与英文缩写相等时,输出数字,哪天的时候直接输出就可以了,但是要注意前导零。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=10010;
typedef long long ll;
string str[13]={"0","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
pair<char,int> p[110];
int main() {
    IOS;
    string s;
    cin>>s;
    for(int i=1;i<=12;i++) {
        if (s.substr(0, 3) == str[i]){
            cout<<i<<' ';
            break;
        }
    }
    if(s[3]=='0')cout<<s[4];
    else cout<<s[3]<<s[4];
    return 0;
}

E题 回文日期

题意:找出给定日期,找出之后符合回文的日期以及满足ABABBABA类型的回文日期。

思路:日期是八位数字,回文就是左边四位和右边四位对称就是会问日期,为了防止超时,所以我们可以用年来遍历,绝对只在10000次,利用对称把年所对应的月和日找出来,判断是不是合法时期,找出来的就是回文日期,然后标记一下,不在找回文日期,而要找满足ABABBABA类型的回文日期,在回文日期的基础上在判断一下满足ABABBABA类型就可以了。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=10010;
typedef long long ll;
int res,ans;
int a1,a2,a3;
int b1,b2,b3;
bool check1(int y,int m,int d)
{
    int mp[13]{0,31,28,31,30,31,30,31,31,30,31,30,31};
    int mr[13]{0,31,29,31,30,31,30,31,31,30,31,30,31};
    if((y%4==0&&y%100!=0)||y%400==0){
        if(m>=1&&m<=12&&d>=0&&d<=mr[m])
            return true;
    }
    else{
        if(m>=1&&m<=12&&d>=0&&d<=mp[m])
            return true;
    }
    return false;
}
bool check2(int y,int m,int d)
{
    int mp[13]{0,31,28,31,30,31,30,31,31,30,31,30,31};
    int mr[13]{0,31,29,31,30,31,30,31,31,30,31,30,31};
    if((y%4==0&&y%100!=0)||y%400==0){
        if(m>=1&&m<=12&&d>=0&&d<=mr[m])
            if(y/1000==y/10%10&&y/100%10==y%10)
            return true;
    }
    else{
        if(m>=1&&m<=12&&d>=0&&d<=mp[m])
            if(y/1000==y/10%10&&y/100%10==y%10)
            return true;
    }
    return false;
}
int main() {
    IOS;
    string s;
    cin >> s;
    int year=(s[0]-'0')*1000+(s[1]-'0')*100+(s[2]-'0')*10+s[3]-'0';
    for(int i=year+1;;i++){
        int month=i%10*10+i/10%10;
        int day=i/100%10*10+i/1000;
        if(res==0&&check1(i,month,day)){
            res=1;
            a1=i,a2=month,a3=day;
        }

        if(ans==0&&check2(i,month,day)){
            ans=1;
            b1=i,b2=month,b3=day;
        }
        if(res==1&&ans==1)break;
    }
    printf("%04d%02d%02d\n",a1,a2,a3);
    printf("%04d%02d%02d\n",b1,b2,b3);
    return 0;
}

F题 平面切分

题意:给你几条直线的斜率和截距,问你这几条直线可以把平面分成几个部分。 思路:找规律,多举几个例子找规律,这样的题一定有规律,可以发现,增加一条直线,不管怎么样平面肯定加一,如果和其他直线有几个交点,就再增加几个平面,考虑这道题有重复的直线和交点,,而重复的对答案没有贡献并且顺序不重要,所以我们使用set这个可以自动去重和排序的容器来存数据,写个函数来计算交点个数,一边输入一边计算。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
typedef double D;
typedef pair<D,D> PDD;
set<PDD> st;
int ans=1;

int cac(D x,D y)
{
    set<PDD> point;
    for(auto it=st.begin();it!=st.end();it++){
        if((it->first)!=x) {
            D xx = ((it->second) - y) / (x - (it->first));
            D yy = xx * x + y;
            point.insert({xx, yy});
        }
    }
    return point.size();
}

int main() {
    IOS;
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        int len = st.size();
        st.insert({x, y});
        if (len != st.size()) {
            ans++;
            ans += cac(x, y);
        }
    }
    cout << ans;
    return 0;
}

G题 走方格

题意:给一个n乘m的地图,从1乘1开始走,只能向右或者向下走,问走到n乘m的走法由多找种。

思路:典型动态规划,也就是线性DP的问题这一格走法只能由它上面一格和左边一格的走法加起来,要注意当从起点开始时有一种走法,如果不初始化,就会全部为零。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=10010;
typedef long long ll;
int dp[40][40];
int main() {
    IOS;
    int n,m;
    cin>>n>>m;
    dp[1][1]=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i==1&&j==1)continue;
            if(i%2==0&j%2==0)dp[i][j]=0;
            else dp[i][j]=dp[i-1][j]+dp[i][j-1];
        }
    }
    cout<<dp[n][m];
    return 0;
}

H题 乘法表

先吐槽一波,我真的服了,结束前一秒,我把上一题改后的代码交到这题,就把他覆盖了,一分没有,哭泣。

题意:打印一个p进制的乘法表,就是表中不能出现大于等于p的数字,只要大于等于p就要进位,还要记得要将大于等于10的数字转化为字母。

思路:打印表达式前两个数字就判断是否需要转化为字母,因为p进制的前两个数字肯定不会超过p肯定不用进位。表达式的值则需要判断是否需要进位和转化为字母,将十进制的转化为p进制的数就除以p取余存到数组中,然后在翻转一下就是p进制的数,然后再判断转化字母就可以了。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=10010;
typedef long long ll;
int main() {
    IOS;
    int n;
    cin >> n;
    for (int i = 1; i < n; i++) {
        for (int j = 1; j <= i; j++) {
            if (i < 10)cout << i << '*';
            else cout << (char) (i + 55) << '*';
            if (j < 10)cout << j << '=';
            else cout << (char) (j + 55) << '=';
            int k = i * j;
            int l = k;
            int a[10010]{}, t = 0;
            while (1) {
                a[t++] = k % n;
                k /= n;
                if (k / n == 0)break;
            }
            if (l >= n)a[t++] = k % n;
            reverse(a, a + t);
            for (int i = 0; i < t; i++) {
                if (a[i] < 10)cout << a[i];
                else cout << (char) (a[i] + 55);
            }
            cout << ' ';
        }
        cout << '\n';
    }
    return 0;
}

SMU Winter 2023 Round #3 (Div.2)

B题 三元组

题意:给一个序列,满足a[i]+a[j]=a[k]并且n≤i≤j≤k≤n 就是一个三元组,计算有多少个三元组

思路:因为此题数据小,直接暴力列一个三重循环,加个限制条件就可以了。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
    int t;
    cin>>t;
    int a[110];
    while(t--){
        int n;cin>>n;
        int ans=0;
        for(int i=0;i<n;i++)cin>>a[i];
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                for(int k=0;k<n;k++){
                    if(a[i]+a[j]==a[k]&&(i<=j&&j<=k&&i<=k))ans++;
                }
            }
        }
        cout<<ans<<'\n';
    }
    return 0;
}

C题 单位转换

题意:给一个字符串,1GB=2^10MB=2^20KB=2^30B,满足这个转换条件,求转换后的数值,保留六位小数。

思路:遍历字符串,找到等号的位置,等号的前一个或者两个就是转换之前的单位,因为判断G,M,K,B就可以了但是B只有一个,而其他的有两个,所以这里要判断一下,并且记录这个字符的位置,以便后面号提取数字,接着就是等号后面两个所在的字符就是转换后的单位,因为正序不需要判断,然后提取数字,将四个字符G,M,K,B存到数组里,遍历数组,看看两个单位之间要除或乘几次,乘除的时候判断一下就可以,记住用double类型。

#include<bits/stdc++.h>
using namespace std;
int g[4]={'B','K','M','G'};
int main() {
    string s;
    cin >> s;
    int i, ret = 0;
    char a, b;
    for (i = 0; i < s.size(); i++) {
        if (s[i] == '=') {
            if (s[i - 2] >= '0' && s[i - 2] <= '9') {
                ret = 1;
                a = s[i - 1];
            } else a = s[i - 2];
            b = s[i + 2];
            break;
        }
    }
    double k = 0;
    int t = 1;
    int h = i;
    if (ret == 1)h = i - 2;
    else h = i - 3;
    for (int j = h; j >= 0; j--) {
        k += (s[j] - '0') * t;
        t *= 10;
    }
    int a1, b1;
    for (int j = 0; j < 4; j++) {
        if (a == g[j])a1 = j;
        if (b == g[j])b1 = j;
    }
    for (int j = min(a1, b1); j < max(a1, b1); j++) {
        if (a1 > b1)k *= 1024;
        if (a1 < b1)k /= 1024;
    }
    //cout<<a<<' '<<b<<' '<<k<<' '<<a1<<' '<<b1<<' ';
    printf("%.6f", k);
    return 0;
}

但是更简单的就是全部转化为B或GB再转化成对应的就可以了,更简单。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
    string s;
    cin >> s;
    char a,b;
    double sum=0;
    for(int i=0;i<s.size();i++){
        if(s[i]>='0'&&s[i]<='9')sum=sum*10+(s[i]-'0');
        else{
            a=s[i];
            break;
        }
    }
    for(int i=0;i<s.size();i++){
        if(s[i]=='='){
            b=s[i+2];
            break;
        }
    }
    //cout<<a<<' '<<b<<' '<<sum<<'\n';
    if(a=='G')sum=sum*pow(2,30);
    if(a=='M')sum=sum*pow(2,20);
    if(a=='K')sum=sum*pow(2,10);
    if(b=='K')sum=sum/pow(2,10);
    if(b=='M')sum=sum/pow(2,20);
    if(b=='G')sum=sum/pow(2,30);
    printf("%.6f",sum);
    return 0;
}

D题 乘方

题意:求a的b次方会不会超过1e9,超过输出-1,没超输出对应得知。 思路;使用pow计算,用int来存,超过就会溢出,不在0到1e9的范围内,判断即可。也可以一个一个的乘,当乘积大于1e9时就输出-1结束程序,否则就乘到结束,最多30 次肯定不会超时。 第一种

#include<iostream>
#include<cmath>
using namespace std;
int a,b,c;
int main(){
    cin>>a>>b;
    c=pow(a,b);
    if(c>0&&c<=1e9)cout<<c;
    else cout<<"-1";
    return 0;
}

第二种

#include<iostream>
#include<cmath>
using namespace std;
int a,b,c;
int main() {
    cin >> a >> b;
    long long ans = 1;
    for (int i = 0; i < b; i++) {
        ans *= a;
        if (ans > 1e9) {
            cout << "-1";
            return 0;
        }
    }
    cout << ans;
    return 0;
}

E题 直播获奖

题意:根据每轮评选的人数计算获奖的人数,在获奖人数中挑选分数最低的就是当时获奖分数线。 思路:可以每轮都排序,从大到小开始选,但是这题的数据范围会TLE。我们这题只关心每个分数的个数,不关心单个数据,所以可以使用桶排序的方式,记录每个分数段的人数即可,遍历一下,直到加到大于等于获奖人数时就输出,就是即时分数线。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=610;
int a[N],b[N];
int main() {
    IOS;
    int n,w;
    cin>>n>>w;
    for(int i=1;i<=n;i++){
        int x;cin>>x;
        a[x]++;
        int p=max(1,i*w/100);
        int cnt=0;
        for(int j=600;j>=0;j--){
            cnt+=a[j];
            if(cnt>=p){
                cout<<j<<' ';
                break;
            }
        }
    }
    return 0;
}

F题 Grave

题意:给一个大长方形和小长方形,问在大小长方形之间能不能放得下一块长方形尺寸的墓碑。 思路:就枚举在大长方形里除小长方形之外空白的四个部分能不能放即可。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
typedef double D;
typedef long long ll;
int main() {
    IOS;
    int x1, y1, x2, y2, x3, y3, x4, y4;
    cin >> x1 >> y1 >> x2 >> y2;
    cin >> x3 >> y3 >> x4 >> y4;
    int x, y;
    cin >> x >> y;
    if (x2 - x4 >= x && y2 - y1 >= y) {
        cout << "Yes" << endl;
        return 0;
    } else if (x3 - x1 >= x && y2 - y1 >= y) {
        cout << "Yes" << endl;
        return 0;
    } else if (x2 - x1 >= x && y3 - y1 >= y) {
        cout << "Yes" << endl;
        return 0;
    } else if (x2 - x1 >= x && y2 - y4 >= y) {
        cout << "Yes" << endl;
        return 0;
    }
    cout << "No" << endl;
    return 0;
}

G题 Bus

题意:总共n个人,过k个站,过一个站下去一个人,再下去车上人数的一半,最后一个站下完刚好每人。 思路:直接倒推回去,从k站开始,往前,向上一半的人数在加一,最后结果就是最开始的人数。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
typedef double D;
typedef long long ll;
int main() {
    IOS;
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int k=0;
        for(int i=1;i<=n;i++){
            k=k*2+1;
        }
        cout<<k<<'\n';
    }
    return 0;
}

H题 Alarm Oclock

题意:每个数字需要对应的火柴,给一个火柴数,问这个火柴数是不是能拼成一个对应时间点,能就输出任意一个答案,不能就输出Impossible。 思路:因为总共的时间为24乘以60等于1440,最多循环这么多次,不会超时,所直接暴力两个循环,外层控制小时内层控制分钟,如果可以拼成,就输出并退出程序就可以了,循环完了都没有找到就输出Impossible。

#include<bits/stdc++.h>
using namespace std;
int a[10]={6,2,5,5,4,5,6,3,7,6};
int n;
int main() {
    cin >> n;
    for (int i = 0; i <= 23; i++) {
        for (int j = 0; j <= 59; j++) {
            int num = 0;
            num =num+ a[i % 10] + a[i / 10] + a[j % 10] + a[j / 10];
            if (num == n) {
                printf("%02d:%02d", i, j);
                return 0;
            }
        }
    }
    cout << "Impossible";
    return 0;
}

I题 采药

题意:计算在规定时间里所采药的最大价值,每株药草只能采一次。

思路:经典的01背包问题,列个状态转移方程即可。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
using namespace std;
int n,t;
int T[1010],Va[1010];
int dp[1010];
int main() {
    IOS;
    cin >> t >> n;
    for (int i = 1; i <= n; i++)cin >> T[i] >> Va[i];
    for (int i = 1; i <= n; i++) {
        for (int j = t; j >= T[i]; j--) {
            dp[j] = max(dp[j], dp[j - T[i]] + Va[i]);
        }
    }
    cout << dp[t];
    return 0;
}

J区间内的真素数

题意:两个数n,m,求从n到m内的真素数,真素数就是正反都是素数,例如13和31都是素数,所以13就是真素数。

思路:写两个函数,一个判断素数,一个求这个数的倒过来的数,先用数组存入一个数的每个位置上的数,在反向输出即可。

#include<bits/stdc++.h>
using namespace std;
int fanxu(int x){
    vector<int>a;
    while(x>0){
        a.push_back(x%10);
        x/=10;
    }
    int num=0;
    for(int i=0;i<a.size();i++)num=num*10+a[i];
    return num;
}
bool isPrime(int x){
    if(x==0||x==1)return false;
    for(int i=2;i*i<=x;i++){
        if(x%i==0)return false;
    }
    return true;
}
int main() {
    int n, m, ret = 0;
    cin >> n >> m;
    for (int i = n; i <= m; i++) {
        int t = fanxu(i);
        if (isPrime(i) && isPrime(t)) {
            if (ret == 0) {
                cout << i;
                ret = 1;
                continue;
            }
            cout << ',' << i;
        }
    }
    if(ret==0)cout<<"No";
    return 0;
}

k题 素数回文数的个数

题意:一个数n,找出从11到n的回文素数的个数,回文就是左右两边对称。

思路:写两个函数,一个判断素数,一个判断回文,判断回文的思路就是把这个数转化成字符串,用两个指针同时从头和尾移动,直到两个指针相等时,只要中间有不相同的,就返回,相等时还没返回就是回文,返回true。

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

bool isPrime(int x) {
    if (x == 0 || x == 1)return false;
    for (int i = 2; i * i <= x; i++) {
        if (x % i == 0)return false;
    }
    return true;
}

bool Huiwen(int x) {
    vector<int> a;
    while (x > 0) {
        a.push_back(x % 10);
        x /= 10;
    }
    int i = 0, j = a.size() - 1;
    while (i <= j) {
        if (a[i++] == a[j--])continue;
        else return false;
    }
    return true;
}
int main() {
    int n, m, ans = 0;
    cin >> n;
    for (int i = 11; i <= n; i++) {
        if (isPrime(i) && Huiwen(i))ans++;
    }
    cout << ans;
    return 0;
}

SMU Winter 2023 Round #4 (Div.2)

A题 川牌

题意;两个在6以内的数x,y。满足1≤x≤y≤6,x+y=k称为川牌,求有几对川牌。 思路;使用两个循环加个限制条件就可以了。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
int main() {
    IOS;
    int t;
    cin>>t;
    while(t--){
        int k,ans=0;
        cin>>k;
        for(int i=1;i<=6;i++)
            for(int j=1;j<=6;j++){
                if(i+j==k&&i<=j)ans++;
            }
        cout<<ans<<'\n';
    }
    return 0;
}

B题 Hotpot

题意:有n个人,有一个锅,有k种食材,给出每个人最爱的食物种类,有最爱的就吃光它,并且幸福值加一,没有就往锅里放自己喜欢吃的。思路:可以知道,两轮人数循环后肯定是一个周期,所以先算一个周期,再用移动次数除以周期再乘以幸福值就可以,再把除了周期剩下的移动次数再跑一遍就可以了。

#include<bits/stdc++.h>
using namespace std;
typedef struct sm{
    int x;
    int y;
}mms;
const int N=1e5+10;
int cnt[N];
int n,k,m;
int main() {
    int t;
    cin >> t;
    while (t--) {
        mms ans[N];
        memset(cnt, 0, sizeof(cnt));
        cin >> n >> k >> m;
        for (int i = 0; i < n; i++)
            cin >> ans[i].x, ans[i].y = 0;//x为每位游客最喜欢的部分
        if (m >= 2 * n) {
            for (int i = 0; i < 2 * n; i++) {
                int a = i % n;//对i进行处理,但次数没变
                if (cnt[ans[a].x] == 0)cnt[ans[a].x]++;
                else {
                    cnt[ans[a].x]--;
                    ans[a].y++;
                }
            }
            for (int i = 0; i < n; i++)
                ans[i].y =ans[i].y* (m / (2 * n));
        }
 
 
        for (int i = 0; i < m % (2 * n); i++) {
            int a = i % n;
            if (cnt[ans[a].x] == 0)cnt[ans[a].x]++;
            else {
                cnt[ans[a].x]--;
                ans[a].y++;
            }
        }
        for (int i = 0; i < n; i++) {
            if (i)cout << " ";
            cout << ans[i].y;
        }
        cout << endl;
    }
    return 0;
}

D题 Rock Paper Scissors

题意:两个人1,2,手里有相同的牌数,分别是石头剪刀布,分别出牌,两张牌为一轮,赢得加一分,平局不加分,输了减一分,1希望分数尽可能小,2希望分数尽可能大。 思路:那就先让1尽可能的输,让2加分,然后再把相同的牌抵消,剩下的就是2输的的情况,减去就可以了。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
int main() {
    IOS;
    int t;
    cin >> t;
    int k=t-1;
    while (t--) {
        int br, bp, bs, dr, dp, ds;
        long long ans = 0;
        cin >> br >> bp >> bs >> dr >> dp >> ds;
        if (br > dp) {
            ans += dp;
            br = br - dp;
            dp=0;
        } else {
            ans += br;
            dp = dp - br;
            br=0;
        }
        if (bp > ds) {
            ans += ds;
            bp = bp - ds;
            ds=0;
        } else {
            ans += bp;
            ds = ds - bp;
            bp=0;
        }
        if (bs > dr) {
            ans += dr;
            bs = bs - dr;
            dr=0;
        } else {
            ans += bs;
            dr = dr - bs;
            bs=0;
        }
        if(dr>=br)dr-=br;
        else dr=0;
        if(dp>=bp)dp-=bp;
        else dp=0;
        if(ds>=bs)ds-=bs;
        else ds=0;
        ans=ans-dr-dp-ds;
        if(k==t)cout<<ans;
        else {
            cout<<'\n';
            cout<<ans;
        }
    }
    return 0;
}

H题 Nihongo wa Muzukashii Desu

按照题目进行模拟一下就可以了

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=1e6+10;
int a[N],b[N];
int main() {
    IOS;
    int t;
    cin>>t;
    while(t--){
        string s,s1;
        cin>>s;
        if(s=="ikimasu"){
            cout<<"itte"<<'\n';
            continue;
        }
        s1=s;
        reverse(s.begin(),s.end());
        if(s.substr(0,7)=="usamihc"){
            for(int i=s.size()-1;i>=7;i--){
                cout<<s[i];
            }
            cout<<"tte"<<'\n';
        }
        else if(s.substr(0,6)=="usamir"){
            for(int i=s.size()-1;i>=6;i--){
                cout<<s[i];
            }
            cout<<"tte"<<'\n';
        }
        else if(s.substr(0,6)=="usamim"){
            for(int i=s.size()-1;i>=6;i--){
                cout<<s[i];
            }
            cout<<"nde"<<'\n';
        }
        else if(s.substr(0,6)=="usamib"){
            for(int i=s.size()-1;i>=6;i--){
                cout<<s[i];
            }
            cout<<"nde"<<'\n';
        }
        else if(s.substr(0,6)=="usamin"){
            for(int i=s.size()-1;i>=6;i--){
                cout<<s[i];
            }
            cout<<"nde"<<'\n';
        }
        else if(s.substr(0,6)=="usamik"){
            for(int i=s.size()-1;i>=6;i--){
                cout<<s[i];
            }
            cout<<"ite"<<'\n';
        }
        else if(s.substr(0,6)=="usamig"){
            for(int i=s.size()-1;i>=6;i--){
                cout<<s[i];
            }
            cout<<"ide"<<'\n';
        }
        else if(s.substr(0,7)=="usamihs"){
            for(int i=s.size()-1;i>=7;i--){
                cout<<s[i];
            }
            cout<<"shite"<<'\n';
        }
    }
    return 0;
}

K题 K-skip Permutation

题意:给一个排列从1到n,求n+k=n+1,出现的次数最多。

思路:就从1开始不断加k并输出直到大于n时,没输出1次就记1次数,直到计数器为n时就停止,输出的就是满足题目的答案。

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=1e6+10;
int a[N],b[N];
int main() {
    IOS;
    int n,k,t=0;
    cin>>n>>k;
    for(int i=1;i<=n;i++){
        if(t==n)break;
        if(t==0)cout<<i;
        else cout<<' '<<i;
        t++;
        int x=i;
        while(1){
            x=x+k;
            if(x<=n&&t<=n){
                cout<<' '<<x;
                t++;
            }
            else break;
        }
    }
    return 0;
}

M题 True story

题意:有n个人,距离机场x,机场的飞机起飞时间是p0,起飞时间会有k次延迟,每个人有一个速度,每个人只有在确定可以在规定时间里到达才会移动,否则就不动,给出延迟宣布的时间和延迟起飞的时间,问最后有几个人到达机场。

思路:在没有进行第一次宣布的时候判断谁能到达机场,并将他的速度赋值为零,然后再每次宣布延迟时间的时候计算新的可以移动的时间,就是宣布得急起飞的时间减去宣布时的时间再乘以速度看看是否大于距离机场的距c。记得开long long 因为这题的数据是1e9,所以在计算距离的时候,可能会爆int,所以开long long.

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr)
using namespace std;
const int N=1e6+10;
int a[N],b[N];
int main() {
    IOS;
    int n,k,x,p0,ans=0;
    int t[100010]{},p[100010]{};
    vector<int> s;
    cin>>n>>k>>x>>p0;
    for(int i=0;i<n;i++){
        int y;cin>>y;
        s.push_back(y);
    }
    sort(s.begin(),s.end());
    for(int i=1;i<=k;i++)cin>>t[i];
    for(int i=1;i<=k;i++)cin>>p[i];
    for(int i=0;i<=k;i++){
        if(i!=0)p0=(p[i]-t[i]);
        for(int j=s.size()-1;j>=0;j--){
            if(s[j]*p0>=x){
                ans++;
                s.pop_back();
            }
            else break;
        }
    }
    cout<<ans;
    return 0;
}