首页 > 其他分享 >训练round1题解

训练round1题解

时间:2023-03-24 23:56:49浏览次数:40  
标签:cout 训练 int 题解 cin long tie round1 define

SMU Spring 2023 Trial Contest Round 1

A.

大意:
给出一个仅由0,1组成的字符串,该字符串是多次在首位各加0或1得到,问最短的原始字符串的长度。

思路:
一次操作增加两个字符,
特判字符串长度为1直接输出1.
首尾双指针进行判断,满足条件同时移动,不满足则退出,答案为原长-2乘以指针移动的次数。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
int main(){
    ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        string s;cin>>s;
        if(s.size()==1){
            cout<<1<<endl;
            continue;
        }
        int l=0,r=s.size()-1;
        while(l<r){
         if((s[l]=='0'&&s[r]=='1')||(s[l]=='1'&&s[r]=='0')){
             l++;r--;
         }else break;
        }
        cout<<s.size()-l*2<<endl;
    }
    return 0;
}

B.

大意:
给定一个字符串,把它分成两部分,使每部分重复的字母最少,计算出两部分不重复字母数之和。

思路:
用map记录字母是否重复,
向右扫一遍,向左扫一遍,两个数组记录在每个位置断开后重复的字母数。
最后遍历一遍找出左右重复字母数和最小的那个位置,输出字符串长度-和。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int N=2e5+10;
vector<int> l(N),r(N);
map<char,int> mp;
int main(){
    ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        string s;cin>>s;
        for(int i=0;i<s.size()-1;i++){
            if(!mp[s[i]]){
                mp[s[i]]=1;
                if(i==0)l[i]=0;
                else l[i]=l[i-1];
            }else{
                l[i]=l[i-1]+1;
            }
        }
        mp.clear();
        for(int i=s.size()-1;i>0;i--){
            if(!mp[s[i]]){
                mp[s[i]]=1;
                if(i==s.size()-1)r[i]=0;
                else r[i]=r[i+1];
            }else{
                r[i]=r[i+1]+1;
            }
        }
        //for(int i=s.size()-1;i>0;i--)cout<<r[i]<<endl;
        int mi=1e7;
        for(int i=0;i<s.size()-1;i++){
            mi=min(l[i]+r[i+1],mi);
        }
        cout<<s.size()-mi<<endl;
        mp.clear();
        l.clear();r.clear();
    }
    return 0;
}

C.

大意:
给出一组数,一次操作可以将相邻两个数符号取反,问经过数次操作后整组数和最大是多少。

思路:
等价于可以任意选两个数取相反符号。
1.若负数个数为偶数,则答案为整组数取正之和。
2.若负数个数为奇数,则看它与最小正数的绝对值,若负数绝对值大则进行操作。
在输入时可以将所有数取正求和,记录负数个数,
若负数个数为奇数,把数排序,删除最小数的2倍。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int N=2e5+10;
int a[N];
int main(){
    ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        ll sum=0;
        int cnt=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            if(a[i]<0){
                cnt++;
                sum-=a[i];
                a[i]=-a[i];
            }else sum+=a[i];
        }
        if(cnt&1){
            sort(a+1,a+1+n);
            cout<<sum-2*a[1]<<endl;
        }else{
            cout<<sum<<endl;
        }
    }
    return 0;
}

E.

思路:
判断数n是否大等于两个最低需求之和,若是,输出一个最低需求和n-该最低需求。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int N=2e5+10;
int a[10][10];
int main(){
    ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
    int n;cin>>n;
    for(int i=1;i<=4;i++){
        for(int j=1;j<=4;j++){
            cin>>a[i][j];
        }
    }
    int x,y;
    x=min(a[1][1],a[1][2]);
    y=min(a[1][3],a[1][4]);
    if(x+y<=n){
        cout<<1<<' '<<x<<' '<< n-x;
        return 0;
    }
    x=min(a[2][1],a[2][2]);
    y=min(a[2][3],a[2][4]);
    if(x+y<=n){
        cout<<2<<' '<<x<<' '<< n-x;
        return 0;
    }
    x=min(a[3][1],a[3][2]);
    y=min(a[3][3],a[3][4]);
    if(x+y<=n){
        cout<<3<<' '<<x<<' '<< n-x;
        return 0;
    }
    x=min(a[4][1],a[4][2]);
    y=min(a[4][3],a[4][4]);
    if(x+y<=n){
        cout<<4<<' '<<x<<' '<< n-x;
        return 0;
    }
    cout<<-1;
    return 0;
}

F.

大意:
给定一组数,(循环式),可选任一个位置开始,给出间隔k,一轮总量是这几个位置上的值相加,问从哪个位置开始使得值最小。

思路:
枚举可以开始的位置:0-k,
数组下标从0开始,这样把位置取个数的模达到循环的作用,
一轮取的个数:n/k

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int N=1e5+10;
int a[N];
int main(){
    ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
    int n,k;cin>>n>>k;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    ll mi=1e9;
    int f=0;
    ll sum,tt;
    for(int i=0;i<k;i++){
        sum=0;
        tt=i;
      //  cout<<"i="<<i<<endl;
      //  cout<<"n/k-1="<<n/k-1<<endl;
       // cout<<"tt="<<tt<<endl;
        sum+=a[tt];
       // cout<<"sum="<<sum<<endl;
        for(int j=1;j<=n/k-1;j++){
            tt+=k;
            sum+=a[tt%n];
         //   cout<<"tt%n="<<tt%n<<endl;
           // cout<<"sum="<<sum<<endl;
        }
        if(sum<mi) {
            mi = sum;
            f = i;
        }
    }
    cout<<f+1;
    return 0;
}

G.

大意:
有n种水果,每种水果有对应的taste和cal,要求选m种水果后taste之和除以cal之和等于k。
问taste之和最大是多少。

思路:
把公式变形,得到(taste-k * cal)之和为0。
将(taste-k * cak)看作体积,
taste看作价值,
装满背包,求最大价值。
正负数分开作两个背包,
相同体积的则满足条件(相减为0)。
最后遍历一遍求最大值。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int N=2e5+10;
const int mod=1e9;
#define inf 0x3f3f3f3f;
int dp[2][100010];
int x,j,ans,n,k,i,a[110],b[110];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    for(i=0;i<2;i++)
        for(j=1;j<100010;j++)
            dp[i][j]=-1*inf;
    dp[0][0]=dp[1][0]=0;
    cin>>n>>k;
    for(i=0;i<n;i++)cin>>a[i];
    for(i=0;i<n;i++){
        cin>>b[i];b[i]=a[i]-b[i]*k;
    }
    for(i=0;i<n;i++){
        if(b[i]>0){
            for(j=100005;j>=b[i];j--){
                dp[0][j]=max(dp[0][j],dp[0][j-b[i]]+a[i]);
            }
        }else{
            x=-1*b[i];
            for(j=100005;j>=x;j--){
                dp[1][j]=max(dp[1][j],dp[1][j-x]+a[i]);
            }
        }
    }
    ans=0;
    for(i=0;i<=100005;i++)ans=max(ans,dp[0][i]+dp[1][i]);
    if(ans==0)cout<<-1;
    else cout<<ans;
    return 0;
}

H.

大意:
给出一个n个点m条边的无向图,每条边有区间l-r,求从1到n路径组成的边集,使该边集中所有区间的交内的正整数元素个数最多。

思路:
dfs深搜,要剪枝。
每个结点结构体存区间信息。
剪枝1:已经更新过的区间比现区间大,不合理过了,剪掉。
剪枝2:现区间比已知答案还小,不是最优解,剪掉。
剪枝3:已经访问过的节点剪掉。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
const int N=1e3+10;
const int mod=1e9;
int n,m;
struct node{
    int v,le,ri;
};
vector<node> g[N];
int ma;
int vis[N],vx[N],vy[N];
void dfs(int u,int l,int r){
    if(u==n){
        ma=max(ma,r-l+1);
        return ;
    }
    for(auto t:g[u]){
        int vv=t.v,left=t.le,right=t.ri;
        if(vis[vv])continue;
        vis[vv]=1;
        int lll=max(l,left),rrr=min(r,right);
        if(vx[vv]<=lll&&vy[vv]>=rrr){
            vis[vv]=0;
            continue;
        }
        if(lll<=rrr&&rrr-lll+1>ma) {
            vx[vv] = lll;vy[vv] = rrr;
            dfs(vv, lll, rrr);
        }
        vis[vv] = 0;
    }
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    int a,b,l,r;
    while(m--){
        cin>>a>>b>>l>>r;
        g[a].push_back({b,l,r});
        g[b].push_back({a,l,r});
    }
    dfs(1,1,1e9);
    if(ma==0)cout<<"Nice work, Dima!";
    else cout<<ma;
    return 0;
}

标签:cout,训练,int,题解,cin,long,tie,round1,define
From: https://www.cnblogs.com/wwww-/p/17253728.html

相关文章

  • 代码随想录算法训练营Day52 动态规划
    代码随想录算法训练营代码随想录算法训练营Day52动态规划|300.最长递增子序列674.最长连续递增序列718.最长重复子数组300.最长递增子序列题目链接:300.最长递增子......
  • Leetcode(剑指offer专项训练)——DP专项(2)
    三角形中最小路径之和1.题目描述给定一个三角形triangle,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。相邻的结点在这里指的是下标与上一......
  • [ABC276G] Count Sequences 题解
    考虑差分,设\(d_i=a_i-a_{i-1}\),特别的,\(d_1=a_1\),那么约束就变成了\(\displaystyle\sumd_i\lem\)。对所有\(i>1\)有\(d_i\not\equiv0\pmod3\)。发现\(d_1\)......
  • CSP20230319-4 星际网络II 题解
    〇、题目题目描述随着星际网络的进一步建设和规模的增大,一个新的问题出现在网络工程师面前——地址空间不够用了!原来,星际网络采用了传统的IPv6协议,虽然有\(2^{128}\)级......
  • 【sklearn版本问题解决】
    一、报错fromsklearn.utils.validationimportcheck_memoryImportError:cannotimportname'check_memory'二、解决1.首先我去看了相关位置的源码发现validation.py里......
  • 关于安装google-colab包速缓慢的问题解决
    最近想从colab上重构源码包在本地实现,但是总有一个包是来自google.colab的fromgoole.colabimportfiles提示没有google.colab的安装模块,需要安装google-colab的这个包......
  • T324159 卡空间的题目/电脑白吃 题解
    https://www.luogu.com.cn/problem/T324159题目大意:给定一个大小为\(n\)的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于\(\lfloor\frac{n}{2}\rfloo......
  • CF1168C And Reachability 题解 线性dp
    题目链接https://codeforces.com/problemset/problem/1168/C题目大意给定一个数组\(a\),从下标\(x\)能够转移到下标\(y\)要满足\(x\lty\)且\(a_{p_i}\,\&\,a......
  • P3489 [POI2009]WIE-Hexer 题解
    一、题目描述:大陆上有 n 个村庄,m 条双向道路,p 种怪物,k 个铁匠,铁匠都在一个村庄里,他可会给你打造他所能打造的所有剑,特定的剑可以对付特定的怪物,每条道路上都可......
  • P4221 [WC2018]州区划分 题解
    题目链接题目描述给出\(n\)个城市,\(m\)条边,一个划分合法当且仅当所有划分中的点集和集合中点之间存在的边集所构成的图不构成欧拉回路且联通。定义一个点集的值为......