2022.4.29

SZTU春季个人训练赛

A - Alphabet

最长上升子序列

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int dp[30];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    string s;
    cin >> s;
    for (int i = 0; i < 30;i++)
        dp[i] = 1;
    for (int i = 1; i < s.length(); i++)
    {
        for (int j = 0; j < i; j++)
        {
            if (s[i] > s[j])
            {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
    }
    int ans = 0;
    for (int i = 0; i <= s.length();i++)
    {
        ans = max(dp[i], ans);
    }
    cout << 26 - ans;
    return 0;
}

B - Barbells

简单搜索 枚举左边放片还是右边放还是不放

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int a[20],b[20],n, m;
set<ll> ans;
void dfs(ll cnt1,ll cnt2,int tot)
{
    if(tot>m)
    {
        if(cnt1==cnt2)
        {
            for (int i = 1;i<=n;i++)
            {
                ans.insert(a[i] + cnt1 + cnt2);
            }
        }
        return;
    }
    dfs(cnt1 + b[tot], cnt2, tot + 1);
    dfs(cnt1, cnt2 + b[tot], tot + 1);
    dfs(cnt1, cnt2, tot + 1);
    return;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m;
    for (int i = 1;i<=n;i++)
    {
        cin >> a[i];
    }
    for (int i = 1;i<=m;i++)
    {
        cin >> b[i];
    }
    dfs(0, 0, 1);
    
    for(auto t:ans)
        cout << t << '\n';
    return 0;
}

D - Cameras

贪心策略,从i+r处开始,如果少于2个摄像头就补全。

#include<bits/stdc++.h>
using namespace std;
bool vis[100005];
int main()
{
    int n,m,r;
    cin>>n>>m>>r;
    for(int i=1;i<=m;i++)
    {
        int x;
        cin>>x;
        vis[x]=1;
    }
    r--;
    int ans=0;
    for(int i=1;i<=n-r;i++)
    {
        int cnt=0;
        for(int j=i+r;j>=i;j--)
        {
            if(vis[j]) cnt++;
            if(cnt==2)
                break;
        }
        if(cnt<2)
        {
            ans+=2-cnt;
            for (int j = i + r; j >= i;j--)
            {
                if(!vis[j])
                {
                    vis[j] = 1;
                    cnt++;
                    if(cnt==2)
                    {
                        break;
                    }
                }
            }
        }
    }
    cout<<ans;
	return 0;
 }

E - Contest Score

比赛时没有读懂题意,罚时与acm类似,k指的是每次最多只能看K个,于是用小根堆存储,当不足k时放入,否则取出堆顶。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    priority_queue<int,vector<int>,greater<int> > que;
    int n, k;
    cin>>n>>k;
    ll cnt = 0, ans = 0;
    for (int i = 1; i <= n;i++)
    {
        int x;
        cin>>x;
        if(que.size()<k)
            que.push(x);
        else
        {
            int t = que.top();
            que.pop();
            ans += t + cnt;
            cnt += t;
            que.push(x);
        }
    }
    while(!que.empty())
    {
        int t = que.top();
        que.pop();
        ans += t + cnt;
        cnt += t;
    }
    cout << ans;
    return 0;
}

F - Equality

代码是比赛时写的,有点奇怪,直接ll和char混合读入即可

#include<bits/stdc++.h>
using namespace std;
int main()
{
	string a,b,c,d,e;
	cin>>a>>b>>c>>d>>e;
	long long x=0,y=0,z=0;

	for(int i=0;i<a.length();i++)
    {
        x=x*10+(a[i]-'0');
    }

    for(int i=0;i<c.length();i++)
    {
        y=y*10+(c[i]-'0');
    }

    for(int i=0;i<e.length();i++)
    {
        z=z*10+(e[i]-'0');
    }
    if(x+y==z)
    {
        cout<<"YES";
    }
    else cout<<"NO";
	return 0;
 }

G - Gravity

Div4 原题

#include<bits/stdc++.h>
using namespace std;
char a[60][60];
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {

            cin>>a[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<n;j++)
        {

            for(int k=1;k<=m;k++)
            {

                if(a[j][k]=='o'&&a[j+1][k]!='#')
                {
                    swap(a[j][k],a[j+1][k]);
                   // a[j][k]=a[j+1][k];
                    //a[j+1][k]='o';
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {

            cout<<a[i][j];
        }
        cout<<'\n';
        }
	return 0;
 }

H - Islands

简单dfs求连通块

#include<bits/stdc++.h>
using namespace std;
char a[60][60];
int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
bool vis[60][60];
int n,m;
bool check(int x,int y)
{

    return x>=1&&x<=n&&y>=1&&y<=m&&a[x][y]!='W';
}
void dfs(int x,int y)
{
    for(int i=0;i<4;i++)
    {

        int xx=x+dx[i],yy=y+dy[i];
        if(check(xx,yy)&&!vis[xx][yy])
        {

            vis[xx][yy]=1;
            dfs(xx,yy);
        }
    }
    return ;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {

            cin>>a[i][j];
        }
    }
    int cnt=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {

           if(!vis[i][j]&&a[i][j]=='L')
           {
               cnt++;
               vis[i][j]=1;
               dfs(i,j);
           }
        }
    }
    cout<<cnt<<'\n';
	return 0;
 }

I - Mismatched Socks

至于全部和还有最大的袜子数有关,当全部和的一半大于mmax时答案为全部和的一半,否则为全部和减去mmax,可以多试试几个样例

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e3+10,INF=1e9;
ll n,a[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    ll mmax = 0,ans = 0;
    for (int i = 1; i <= n;i++)
    {
        cin >> a[i];
        ans += a[i];
        mmax = max(mmax, a[i]);
    }
    if(ans >= mmax * 2)
        ans /= 2;
    else
        ans -= mmax;
    cout << ans;
    return 0;
}

J - Postman

为了尽可能减少路程我们希望从远到近送信,于是将所有坐标从小到大排序,分别处理<0和>=0的部分。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e3+10,INF=1e9;
struct node
{
    ll pos, x;
} a[N];
bool cmp(node a,node b)
{
    return a.pos < b.pos;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll n,k;
    cin >> n >> k;
    for (int i = 1; i <= n;i++)
    {
        cin >> a[i].pos >> a[i].x;
    }
    sort(a + 1, a + 1 + n, cmp);
    ll ans = 0, now = n;
    while(now>=1)
    {
        if(a[now].pos<0)
            break;
        ll cnt = (a[now].x + k - 1) / k;
        ans += cnt * a[now].pos;
        ll sum = cnt * k;
        while(sum&&a[now].pos>=0&&now>=1)
        {
            if(a[now].x<=sum)
                sum -= a[now].x;
            else
            {
                a[now].x -= sum;
                break;
            }
            now--;
        }
    }
    now = 1;
    while(now<=n)
    {
        if(a[now].pos>=0)
            break;
        ll cnt = (a[now].x + k - 1) / k;
        ans -= cnt * a[now].pos;
        ll sum = cnt * k;
        while(sum&&a[now].pos<0&&now<=n)
        {
            if(a[now].x<=sum)
                sum -= a[now].x;
            else
            {
                a[now].x -= sum;
                break;
            }
            now++;
        }
    }
    cout << ans * 2;
    return 0;
}

K - Six Sides

再次读错题。。。以为是把6次掷骰子的点数都告诉了没想到是随机的。。。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int a[10], b[10];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    for (int i = 1; i <= 6;i++)
    {
        cin >> a[i];
    }
    for (int i = 1; i <= 6;i++)
    {
        cin >> b[i];
    }
    int cnt1 = 0, cnt2 = 0;
    for (int i = 1; i <= 6;i++)
    {
        for (int j = 1; j <= 6;j++)
        {
            if(a[i]>b[j])
                cnt1++;
            if(a[i]<b[j])
                cnt2++;
        }
    }
    printf("%.5f", 1.0 * (cnt1) / (cnt1 + cnt2));
    return 0;
}

L - Three Square

没什么办法,看题解直接分情况讨论

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int a1, b1, a2, b2, a3, b3;
    cin >> a1 >> b1 >> a2 >> b2 >> a3 >> b3;
    int a = max(a1, b1);
    int b = max(a2, b2);
    int c = max(a3, b3);
    int mmax = a, t = 1;
    if(b>mmax)
    {
        mmax = b;
        t = 2;
    }
    if(c>mmax)
    {
        mmax = c;
        t = 3;
    }
    int e, f, g, h;
    if(t==1)
    {
        e = a2 + a3;
        f = a2 + b3;
        g = b2 + a3;
        h = b3 + b2;
        if(e==mmax)
        {
            if(b2==b3&&(b2+a1==mmax||b2+b1==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
        if(f==mmax)
        {
            if(b2==a3&&(b2+a1==mmax||b2+b1==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
        if(g==mmax)
        {
            if(a2==b3&&(a2+a1==mmax||a2+b1==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
        if(h==mmax)
        {
            if(a2==a3&&(a2+a1==mmax||a2+b1==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
    }
    else if(t==2)
    {
        e = a1 + a3;
        f = a1 + b3;
        g = b1 + a3;
        h = b1 + b3;
        if(e==mmax)
        {
            if(b1==b3&&(b1+a2==mmax||b1+b2==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
        if(f==mmax)
        {
            if(b1==a3&&(b1+a2==mmax||b1+b2==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
        if(g==mmax)
        {
            if(a1==b3&&(a1+a2==mmax||a1+b2==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
        if(h==mmax)
        {
            if(a1==a3&&(a1+a2==mmax||a1+b2==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
    }
    else
    {
        e = a1 + a2;
        f = a1 + b2;
        g = b1 + a2;
        h = b1 + b2;
        if(e==mmax)
        {
            if(b1==b2&&(b1+a3==mmax||b1+b3==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
        if(f==mmax)
        {
            if(b1==a2&&(b1+a3==mmax||b1+b3==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
        if(g==mmax)
        {
            if(a1==b2&&(a1+a3==mmax||a1+b3==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
        if(h==mmax)
        {
            if(a1==a2&&(a1+a3==mmax||a1+b3==mmax))
            {
                cout << "YES";
                return 0;
            }
        }
    }
    cout << "NO";
    return 0;
}

M - Zigzag

最长交错子序列

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int a[55], dp1[55], dp2[55];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    for (int i = 1; i <= n;i++)
    {
        cin >> a[i];
        dp1[i] = dp2[i] = 1;
    }
    for (int i = 2; i <= n;i++)
    {
        for (int j = 1; j < i;j++)
        {
            if(a[i]>a[j])
                dp1[i] = max(dp1[i], dp2[j] + 1);
            if(a[i]<a[j])
                dp2[i] = max(dp2[i], dp1[j] + 1);
        }
    }
    int ans = 1;
    for (int i = 1; i <= n;i++)
    {
        ans = max({ans, dp1[i], dp2[i]});
    }
    cout << ans;
    return 0;
}
posted @ 2022-04-29 16:50  menitrust  阅读(18)  评论(0编辑  收藏  举报