Codeforces Round 954 (Div. 3)

A. X Axis
1.既然要求每个点到a到距离之和最小,不妨让点a为3个点中的中间点,也就是先对三个数从小到大排序,然后输出首尾数减中间值的绝对值之和即可

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define x first
#define y second
typedef pair<int,int> pii;
#define all(v) v.begin(),v.end()
void solve()
{
	int a[3];
	for(int i=0;i<3;i++)
	{
		cin>>a[i];
	}
	
	sort(a,a+3);
	cout<<abs(a[0]-a[1])+abs(a[2]-a[1]);
	cout<<endl;
	
	
}


signed main()
{
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
	
	
	
}

B. Matrix Stabilization
1.显然如果一个数比它上下左右四个相邻的数大,它就会转化成这四个数中最大的数

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};

void solve()
{
    int n,m;
    cin>>n>>m;
    int a[105][105];
     for(int i=0;i<n;i++){
         for(int j=0;j<m;j++)
         {
             cin>>a[i][j];
         }
     }
     
     for(int i=0;i<n;i++)
     {
         for(int j=0;j<m;j++)
         {
             int ma=-1;
             if(i>0) ma=max(ma,a[i-1][j]);
             if(i<n-1) ma=max(ma,a[i+1][j]);
             if(j>0) ma=max(ma,a[i][j-1]);
             if(j<m-1) ma=max(ma,a[i][j+1]);
             //先找了合法的上下左右的最大值
             //然后比较这个最大值和当前位置的值,如果这个位置的值大于这个最大值就更新
             cout<<min(ma,a[i][j])<<" ";
         }
         cout<<endl;
     }
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1;
    cin>>t;
    while(t--) solve();
    return 0;
}

C. Update Queries
1.因为我们可以改变字符串c的下标和索引数组,那么假如说索引数组中,没有重复的数字,也就是s中一个字符只被修改一次,那么将c按字典序排序,索引组也从小到大排序,自然修改后的s就是字典序最小的。
2.当索引数组有重复数字也没关系,因为我们可以把多余的那些次数用字典序大的字符来消耗掉,那么最终也变成了1中的操作步骤,所以答案就是我们先对c排序,然后按照索引从小到大修改即可

#include <bits/stdc++.h>
using namespace std;
#define int long long 
#define x first
#define y second
typedef pair<int,int> pii;
#define all(v) v.begin(),v.end()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};


void solve()
{
	int n,m;
	map<int,int>mp;
	cin>>n>>m;
	string s1;
	cin>>s1;
	int a[100005];
	for(int i=0;i<m;i++) 
	{
		cin>>a[i];
		mp[a[i]-1]=1;
}
	
	string  s2;
	int p=0;
	cin>>s2;
	sort(all(s2));
//	cout<<s1<<" "<<s2;
	//cout<<endl;
	for(int i=0;i<s1.size();i++)
	{
		if(mp[i]==1)
		{
		if(p<s2.size())	s1[i]=s2[p++];
		}
	}
	cout<<s1<<endl;
}


signed main()
{
	int t;
	cin>>t;
	while(t--)
	{
		solve();
	}
	
	
	
}

D. Mathematical Problem
1.因为只放n-2个符号,所以一定有一个数是两位数,并且因为只有+和✖️。
2.我们可以枚举这个两位数,然后算出每种的结果,比较找最大值即可
3.当我们一种方案里有0的时候,可以全部用乘号让结果为0,即为最小,当一种方案有数字1,我们用乘1让其保持不变,其余的数用加法,结果便为最小

#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
typedef pair<int,int> pii;
#define x first
#define y second
#define all(v) v.begin(),v.end()
int dx[]={0,1,-1,0};
int dy[]={-1,0,0,1};

void solve()
{
    int n; cin>>n;
    string s; cin>>s;
    int ve[n];
    for(int i=0;i<n;i++)
    {
        ve[i]=s[i]-'0';
    }
    int res=1e9;
    //因为只能添加n-2个符号,所以有一个数字肯定是两位数
    for(int i=1;i<n;i++)//i从1开始 因为j要==i-1
    {
         vector<int>num;
        for(int j=0;j<n;j++)
        {
            if(j==i-1){//放这个两位数进去
                int x=ve[j]*10+ve[j+1];
                num.push_back(x);
                j++;//这里把下一位用了 j记得++
            }else{//放一位数进去
                num.push_back(ve[j]);
            }
        }
        //检查这些数 如果有0 相当于全用乘法可以得到最小值为0
        //如果某个数为1,相当于乘1,不改变数的值
        //其余的数全部用加法即可以得到值最小
        int ans=0;
        for(int i=0;i<num.size();i++)
        {
            if(num[i]==0){
                cout<<0<<endl;
                return;
            }else if(num[i]==1)
            {
                continue;
            }else{
                ans+=num[i];
            }
        }
         if(ans==0) ans++; //如果没有输出0,但ans为0,可能是1 01这种情况
        res=min(ans,res);
        
        
    }
    cout<<res<<endl;
    
    
}


signed main()
{
    ios::sync_with_stdio(0),cin.tie(0);
    int t=1;
    cin>>t;
    while(t--) solve();
    return 0;
}

posted on 2024-07-11 13:47  swj2529411658  阅读(10)  评论(0编辑  收藏  举报

导航