AtCoder ABC 247

A Move Right(水)

字符串右移一位 然后在左边补0

void solve()
{
    string s;
    cin >> s;
    s = '0' + s;
    s.erase(s.end() - 1);
    cout << s;
}

B Unique Nicknames(读题)

Description:

​ 每个人有两个备选名字 然后要给每个人从这两个里选一个命名

​ 要求任一人的名字 不能跟其他人的备选名字相同

Solution:

​ map存一下每个名字出现的次数 如果说一个人的两个名字都是出现了两次以上的 那就不行

​ 如果说一个人的备选名字相同的话 只用存一次(自行编写数据hack可得)

Code:

map<string, int> mp;
vector<pair<string, string> > q;

void solve()
{
    int n;
    cin >> n;
    string a, b;
    rep(i, 0, n)
    {
        cin >> a >> b;
        q.pb({a, b});
        if(a == b)  
        	mp[a] ++;
        else 
            mp[a] ++; mp[b] ++;
    }
 
    bool ok = true;
    rep(i, 0, n)
        if(mp[q[i].fi] >= 2 && mp[q[i].se] >= 2)    ok = false;
        
    if(ok)  puts("Yes");
    else puts("No");
}

C 1 2 1 3 1 2 1(递归)

Description:

​ 给定s(n) 要求输出s(n-1) n s(n-1)

​ 当n == 1 输出1 当n == 2 输出 1 2 1

Solution:

​ 递归模拟题意即可

Code:

void f(int x)
{
    if(x == 1)    {cout << 1 << ' '; return;}
    f(x - 1);
    cout << x << ' ';
    f(x - 1);
}
 
void solve()
{
    int n;
    cin >> n;
    f(n);
}

D Cylinder(模拟)

Description:

​ op1 在右端放入价值为x 数量为c的球 op2 从左端取出数量为c的球 并输出其价值和

Solution:

​ 先进先出 队列模拟即可 (队列里的元素是可以更改的 我sb了

Code:

queue<PII> q;
void solve()
{
    int Q;
    scanf("%d", &Q);
    int op, x, c;
    while(Q--)
    {
        scanf("%d", &op);
        if(op == 1)
        {
            scanf("%d%d", &x, &c); //fi: sum se: val
            q.push({c, x});
        }
        else 
        {
            scanf("%d", &c);
            LL res = 0;
            while(c)
            {
                LL d = c - q.front().fi < 0 ? c : q.front().fi; //特判一下就好
                q.front().fi -= d;
                c -= d;
                res += d * 1LL * q.front().se;
                if(q.front().fi == 0)   q.pop();
            }
            printf("%lld\n", res);
        }
    }
}

E Max Min(状压DP)

Description:

​ 给定数组长度为n的数组a 给定x 和 y

​ 要求寻找区间[l, r]的个数 区间要满足区间内所有元素小于等于x 大于等于y 且区间中必须存在x和y

Solution:

​ 首先定义一个dp数组 dp[i] [2] [2] 表示当前的右端点是i 然后区间内是否含有x 区间内是否含有y

​ 转移的时候呢 i可以向i+1转移 并i+1继承i中满足题意的状态 也就是区间上的连续的意思

​ 转移方程写为

rep(j, 0, 2)
	rep(k, 0, 2)
		dp[i][fx | j][fy | k] += dp[i - 1][j][k];

Code:

const int N = 200010;
int n, x, y, q[N], dp[N][2][2]; //以i为右端点的状态 1 1表示满足题意
LL res; 

void solve()
{
    scanf("%d%d%d", &n, &x, &y);
    rep(i, 1, n + 1)
        scanf("%d", &q[i]);

    dp[0][0][0] = 0;
    rep(i, 1, n + 1)
    {
        if(q[i] < y || q[i] > x)    continue; //dp[i][1][1] = 0;区间无法连续了
        int fx = q[i] == x, fy = q[i] == y; //满足存在x或y
        dp[i][fs][ft] += 1;
        rep(j, 0, 2)
            rep(k, 0, 2)
                dp[i][j | fx][k | fy] += dp[i - 1][j][k]; 
                //对于上一个状态而言 如果可以转移的话就相加
                
        res += dp[i][1][1]; //满足题意的情况
    }
    cout << res << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值