我们一起来吐槽 2021四川省 icpc


从 签到 到 不会

A Chuanpai

题意

牌面1~6
能不能凑出k点
有多少种方式凑出k点

思路

都1~6了有啥好说的咧
注意不重复

AC代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1E5 + 7;

#define INF ~0ULL

int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int k;
        cin >> k;
        int ans = 0;
        for (int i = 1; i <= 6; i++)
        {
            if(k-i<=6&&k-i>=i)
            ans++;
        }
        cout<<ans<<endl;
    }
   // system("pause");
}

K-skip Permutation

题意

给你两个数
n,k
n代表(1~n)
k代表差距
构造一个数组
使得ai + k = ai+1
这样的i最多可以是多少

思路

最后一个输出不许出现空格
wogiao
那就计数呗
遍历一遍

AC代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1E5 + 7;
#define INF ~0ULL

int main()
{
    int n, k;
    cin >> n >> k;
    int cnt = 0;
    for(int i=1;i<=k;i++)
    {
        for(int j=0;j*k+i<=n;j++){
            ++cnt;
            if(cnt<n)
            cout<<j*k+i<<" ";
            else
            cout<<j*k+i;
        }
    }
}

D:Rock Paper Scissors

题意

石头剪刀布
两人玩
A想输,B想赢
每次都是A先手,B看到A展示结果在出牌
俩人总牌面一样多
问最后总得分

思路

直接模拟a出牌
b再出牌结果就好了
当然不是一张一张出牌了
a作为先手
是没有决定权
所以最开始是加分
中间是平局
最后是减分

AC代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1E5 + 7;
#define ULL unsigned long long
#define INF ~0ULL
#define pii pair<int, int>
int t, n, m;

int main()
{
    cin >> t;
    while (t--)
    {
        ll a, b, c, x, y, z;
        cin >> a >> b >> c >> x >> y >> z;
        ll ans=0;
        ans+=(min(a,y)+min(b,z)+min(c,x));//dwin
        ll mina = min(a,y),minb =min(b,z),minc =min(c,x);
        a-=mina,y-=mina,b-=minb,z-=minb,c-=minc,x-=minc;

        mina =min(a,x),minb = min(b,y),minc =min(c,z);
        a-=mina,x-=mina,b-=minb,y-=minb,c-=minc,z-=minc;

        ans-=(a+b+c);
        cout<<ans<<endl;
    }
    //system("pause");
}

H:日本语 wa Muzukashii D

题意

什么样的后缀变成什么样的后缀

思路

模拟

AC代码

#include <bits/stdc++.h>
using namespace std;
char *suffix[10] = {"chimasu", "rimasu", "mimasu", "bimasu", "nimasu", "kimasu", "gimasu", "shimasu", "imasu"}; //后缀
int main()
{
    int t;
    char word[30];
    scanf("%d", &t);
    char *p;
    while (t--)
    {

        scanf("%s", word);
        if (!strcmp(word, "ikimasu"))
        {
            printf("itte\n");
            continue;
        }



        int i;
        for (i = 0; i < 9; i++)
        {
            if (strstr(word, suffix[i]))
            {
                p = strstr(word, suffix[i]); //用strstr函数寻找子串(后缀),若找到,返回子串所在的指针,若找不到,返回NULL
                break;
            }
        }
        int T = i + 1;
        char prefix[25]; //前缀
        int t = p - word;//index-arr
        for (i = 0; i < t; i++)
        {
            prefix[i] = word[i];
        }
        prefix[i] = '\0';
        if (T >= 1 && T <= 2)
            printf("%stte\n", prefix);
        else if (T > 2 && T <= 5)
            printf("%snde\n", prefix);
        else if (T == 6)
            printf("%site\n", prefix);
        else if (T == 7)
            printf("%side\n", prefix);
        else if (T == 8)
            printf("%sshite\n", prefix);
        else if (T == 9)
            printf("%stte\n", prefix);
    }
    return 0;
}

M:True Story

题意

4 3 10 4
1 5 2 1
3 4 5
7 9 10
看数据解释
第一行,4表示有四个人要去赶飞机,3代表手机将接受到三次飞
机延误的信息,10代表候机场距离飞机出发的距离,4代表飞机计划起飞时间
第二行代表四个人的速度
第三行代表三次接受到飞机延误的时刻
第四行代表飞机将延误到什么时候
一个人只有觉得有足够时间抵达登机口才会出发
问有多少人是可以出发的

思路

首先对于第二行的速度可以转化为所需时间,记得向上取整
对于每一个人,如果时间不足以到达登机口就不去了
所以每一个人要么停留,要么出发,而且飞机延误的
时刻都将比之前的时刻数大,也就是第四行数字是严格递增的
那么找到每一个通知的从通知
时刻到起飞时刻的最大时长比抵达时长长就好了

AC代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N =1E5+7;
#define ULL unsigned long long
#define INF ~0ULL
#define pii pair<int,int>
int n,k,r,p0;

int tim[N];
pii cc[N];


int main(){
    cin>>n>>k>>r>>p0;
    int now;
    for(int i=1;i<=n;i++){
        cin>>now;
        tim[i] = r/now; 
        if(r%now!=0)
        tim[i]++;
    }
    for(int i=1;i<=k;i++){
        cin>>cc[i].first;
    }
    for(int i=1;i<=n;i++){
        cin>>cc[i].second;
    }
    cc[0].first = 0;
    cc[0].second=p0;
    int maxv = 0;
    for(int i=0;i<=k;i++){
        maxv = max(maxv,cc[i].second-cc[i].first);
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        if(tim[i]<=maxv) ans++;
    }
    cout<<ans<<endl;
    //system("pause");
}

L:Spicy Restaurant

题意

4 4 5
5 4 2 3
1 2
2 3
3 4
4 1
1 1
1 2
1 3
1 4
1 5
4个餐馆,4条边,5个询问
第二行代表四个餐馆的辣味值
接下来4行代表餐馆a到b有无向边
再接下来是5个询问
询问中a,b;代表这个人所在餐馆位置,b代表能够接受的辣味值,可以更小
问满足此询问的餐馆的最近位置,没有输出-1

思路

辣味值只有100
那么我们可以跑100*1E5的BFS
将每个滋味到其他餐馆的距离打出表来
dis [ i ] [ j ] 代表在位置j上,距离j最近的辣味值为i的餐馆的距离
然后我们践行辣味可以更小

AC代码

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
const int N = 2e5 + 7;
int n, e, q, inf, dis[107][N], w[N];
vector<int> g[N];

void BFS(int c)
{
    queue<int> q;
    for (int j = 1; j <= n; j++)
        if (w[j] == c)
            q.push(j), dis[c][j] = 0; //将0点都送进去
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        for (auto v : g[u])
        {
            if (dis[c][v] != inf)
                continue;
            q.push(v);
            dis[c][v] = dis[c][u] + 1;
        }
    }

}

int main()
{
    memset(dis, 0x3f, sizeof dis);
    inf = dis[0][0];
    cin >> n >> e >> q;
    for (int i = 1; i <= n; i++)
        cin >> w[i];
    for (int i = 1; i <= e; i++)
    {
        int x, y;
        cin >> x >> y;
        g[x].pb(y);
        g[y].pb(x);
    }
    for (int i = 1; i <= 100; i++)
        BFS(i);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= 100; j++)
            dis[j][i] = min(dis[j][i], dis[j - 1][i]);
    while(q--)
    {
        int pos,weight;
        scanf("%d%d",&pos,&weight);
        printf("%d\n",dis[weight][pos]==inf?-1:dis[weight][pos]);
    }
}

题意

n个人吃火锅
火锅最开始啥也没有
有m种食材
如果这个人在火锅里有自己喜欢吃的食物,他就快乐加1
否则就投放自己喜欢的食物
然后执行k次操作
问最后每个人的快乐值

思路

k有点大,直接模拟有点,注意最多2*n次,火锅必空,回到原始著状态

AC代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1E5 + 7;
#define ULL unsigned long long
#define INF ~0ULL
#define pii pair<int, int>
int t, n, m;
int arr[N];
int food[N];
int res[N];
int ans[N];

void solve()
{
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= n; i++)
        scanf("%d", &arr[i]);
    memset(food, 0, sizeof food);
    memset(res, 0, sizeof res);
    //memset(ans, 0, sizeof ans);

    for (int i = 1; i <= n; i++)
    {
        if (food[arr[i]] == 1)
        {
            res[i]++;
            food[arr[i]] = 0;
        }
        else
            food[arr[i]]++;
    }
    for (int i = 1; i <= n; i++)
    {
        if (food[arr[i]] == 1)
        {
            res[i]++;
            food[arr[i]] = 0;
        }
        else
            food[arr[i]]++;
    }

    int base = k / (2 * n);
    for (int i = 1; i <= n; i++)
        ans[i] = base * res[i];

    k %= (2 * n);

   // memset(food, 0, sizeof food);

    if (k > n)
    {
        for (int i = 1; i <= n; i++)
        {
            if (food[arr[i]] == 1)
            {
                ans[i]++;
                food[arr[i]] = 0;
            }
            else
                food[arr[i]]++;
        }
        k %= n;
        for (int i = 1; i <= k; i++)
        {
            if (food[arr[i]] == 1)
            {
                ans[i]++;
                food[arr[i]] = 0;
            }
            else
                food[arr[i]]++;
        }
    }
    else
    {
        for (int i = 1; i <= k; i++)
        {
            if (food[arr[i]] == 1)
            {
                ans[i]++;
                food[arr[i]] = 0;
            }
            else
                food[arr[i]]++;
        }
    }
    for(int i=1;i<n;i++){
        cout<<ans[i]<<" ";
    }
    cout<<ans[n]<<endl;
}
int main()
{
    int t;
    cin >> t;
    while (t--)
        solve();
    //system("pause");
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.0-0.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值