zoukankan      html  css  js  c++  java
  • codeforces思维题专练1

    1.Technocup 2021 - Elimination Round 1 A New Technique

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    #define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
    #define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
    #define pb push_back
    #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    /*
    已知每行的相关顺序,
    但不知道行的层次,通过列来找到行的层次
    因为每一行的第一个元素就决定了该行剩余元素的排列,
    所以确定每一行第一个元素的层次也就是,该行在第几行就行了
    */
    typedef long long ll;
    const int N=510;
    int a[N][N],b[N][N];
    
    int main()
    {
        IOS;
        int t;cin>>t;
        while(t--)
        {
            int n,m;cin>>n>>m;
            rep(i,0,n)
                rep(j,0,m)
                    cin>>a[i][j];
            rep(i,0,m)
                rep(j,0,n)  
                    cin>>b[i][j];
            vector<int>ans;
            rep(i,0,n)
            {
                bool flag=false;
                rep(j,0,n)
                {
                    rep(k,0,m)
                    {
                        if(b[0][i]==a[j][k])
                        {
                            ans.pb(j);
                            flag=1;
                            break;
                        }
                    }
                    if(flag)
                        break;
                }
            }
            rep(i,0,n)
            {
                rep(j,0,m)
                    cout<<a[ans[i]][j]<<" ";
                cout<<endl;
            }
        }
        return 0;
    }
    

    2.Codeforces Raif Round 1 (Div. 1 + Div. 2) B - Belted Rooms

    算法想假了真的无语

    假算法
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    #define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
    #define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
    #define pb push_back
    #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    
    typedef long long ll;
    const int N=3e5+10;
    int id[N],od[N];
    /*
    假的算法,出度入度并不直接A能否返回A
    */
    int main()
    {
        IOS;
        int t;cin>>t;
        while(t--)
        {
            memset(id,0,sizeof id);
            memset(od,0,sizeof od);
            int n;char s[N];
            int cnta=0;
            cin>>n>>s+1;
            //第i个符号会影响第i和i+1个点. 
            // for(int i=1;i<n;i++)
            //     cout<<s[i]<<" ";
            // cout<<endl;
            for(int i=1;i<n;i++)
            {
                if(s[i]=='-')
                {
                    cnta++;
                    id[(i+1)]++,id[i]++;
                    od[(i+1)]++,od[i]++;
                }
                else if(s[i]=='>')
                {
                    id[(i+1)]++,od[i]++;
                }
                else if(s[i]=='<')
                {
                    id[i]++,od[(i+1)]++;
                }
            }
            if(s[n]=='-')
            {
                cnta++;
                id[1]++,id[n]++;
                od[1]++,od[n]++;
            }
            else if(s[n]=='>')
            {
                id[1]++,od[n]++;
            }
            else
            {
                id[n]++,od[1]++;
            }
            
            int cnt=0;
            bool flag=true;
            for(int i=1;i<=n;i++)
            {
                // cout<<id[i]<<" "<<od[i]<<endl;
                if(!od[i]||!id[i])
                {
                    flag=false;
                }
                if(id[i]&&od[i])
                    cnt++;
            }
            if(cnta)
                cout<<cnt<<endl;
            else
            {
                if(flag==false)
                    cout<<0<<endl;
                else
                    cout<<cnt<<endl;
            }
        }
        
        return 0;
    }
    
    正解
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    #define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
    #define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
    #define pb push_back
    #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    
    int main(){
        IOS;
        int t;cin>>t;
        while(t--){
            int n;cin>>n;
            string s;cin>>s;
            bool hasCw=false,hasAcw=false;
            for(int i=0;i<n;i++){
                if(s[i]=='<')
                    hasAcw=true;
                if(s[i]=='>')
                    hasCw=true;
            }
            if(hasCw&&hasAcw){
                int ans=0;
                s+=s[0];//好巧妙,运用了string的特点,使得循环变成的顺序
                for(int i=0;i<n;i++){
                    if(s[i]=='-'||s[i+1]=='-')
                        ans++;
                }
                cout<<ans<<endl;
            }
            else{
                cout<<n<<endl;
            }
        }
        
        return 0;
    }
    

    3.Educational Codeforces Round 96 (Rated for Div. 2) C. Numbers on Whiteboard

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    #define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
    #define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
    #define pb push_back
    #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    
    typedef long long ll;
    const int N=3e5+10;
    
    int main()
    {
        IOS;
        int t;cin>>t;
        while(t--)
        {
            int n;cin>>n;
            cout<<2<<endl;
            if(n==2)
                cout<<2<<" "<<1<<endl;
            else
            {
                cout<<n-1<<" "<<n<<endl;
                for(int i=n-2;i>=1;i--)
                    cout<<i<<" "<<i+2<<endl;
            }
        }
        
        return 0;
    }
    

    4.Codeforces Round #675 (Div. 2) B. Nice Matrix

    ( 观察到,若让矩形是回文的必有a[i][j]=a[n-i+1][j]=a[i][m-j+1],(数组下标为a[1sim n,1sim m])\ a[i][j]=a[n-i-1][j]=a[i][m-j-1],(数组下标为a[0sim n-1,0sim m-1])\ )

    想假的算法
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    #define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
    #define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
    #define pb push_back
    #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    
    typedef long long ll;
    const int N=110;
    int a[N][N];
    int main()
    {
        IOS;
        int t;cin>>t;
        while(t--)
        {
            int sum=0;
            memset(a,0,sizeof a);
            int n,m;cin>>n>>m;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    cin>>a[i][j];
                    sum+=a[i][j];
                }
            }
            // cout<<sum<<endl;
            sum=sum/m/n;
            // cout<<sum<<endl;
            ll cnt=0;
            rep(i,a,n)
            {
                rep(j,a,m)
                {
                    if(sum>=a[i][j])
                        cnt+=sum-a[i][j];
                    else
                        cnt+=a[i][j]-sum;
                }
            }
            cout<<cnt<<endl;
        }
        return 0;
    }
    /*
    4 2
    
    4 2
    2 4
    4 2
    2 4
    
    10+26+48==84/12==7
    6+5+4+3
    +2+1+1+2+3+4+11==21+10+11==42
    对于
    3*4
    
    a[2][2]=a[2][2]=a[1][3]=a[2][3]
    */
    
    正解
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    using namespace std;
    #define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
    #define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
    #define pb push_back
    #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    
    typedef long long ll;
    const int N=110;
    int a[N][N];
    int main()
    {
        IOS;
        int t;cin>>t;
        while(t--)
        {
            int n,m;cin>>n>>m;
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<m;j++)
                {
                    cin>>a[i][j];
                }
            }
            ll cnt=0;
            rep(i,a,n)
            {
                rep(j,a,m)
                {
                    vector<int>ans;
    
                    ans.pb(a[i][j]);
                    ans.pb(a[n-i-1][j]);
                    ans.pb(a[i][m-j-1]);
                    sort(ans.begin(),ans.end());
                    // for(auto x:ans)
                    //     cout<<x<<" ";
                    // cout<<endl;
                    cnt+=ans[1]-ans[0];
                    cnt+=ans[2]-ans[1];
                    a[i][j]=a[n-i-1][j]=a[i][m-j-1]=ans[1];
                }
            }
            cout<<cnt<<endl;
        }
        
        return 0;
    }
    

    6.Codeforces Round #670 (Div. 2) B. Maximum Product

    ( 一开始这题完全没有思路,一开始认为是从原数组中不打乱顺序求出5个数乘积的最大值(被迷惑了,大雾)\ 后来看了人家的题解,发现虽然这五个数是有顺序的,但题目没说不能乱序啊!拿出5个数来,数字的下标当然不同了\ 分析符号,首先降序排序 1.如果全正或全负,前五个数的乘积最大,如果升序排序则要多写一个乘积\ 2.当有正有负时,负数的个数必须是0,2,4,5,其中0,5已经被讨论过了 所以再取2和4个负数,再乘积,最后比较3个乘积的最大值输出即可 )

    法一

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    using namespace std;
    #define rep(i,a,n) for(int i=0;i<n;i++)//repeat 默认升序
    #define per(i,a,n) for(int i=n;i>=0;i--)//per 对rep的颠倒,默认降序
    #define pb push_back
    #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    
    typedef long long ll;
    const int N=111000;
    int t;
    ll n;
    ll a[N];
    bool cmp(ll a,ll b)
    {
        return a>b;
    }
    int main() {
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        cin>>t;
        while(t--){
        	cin>>n;
        	for(int i=1;i<=n;++i){
        		cin>>a[i];
        	}
        	sort(a+1,a+1+n,cmp);
        	ll cnt1=a[1]*a[2]*a[3]*a[4]*a[5];
        	ll cnt2=a[1]*a[2]*a[3]*a[n]*a[n-1];
        	ll cnt3=a[1]*a[n]*a[n-1]*a[n-2]*a[n-3];
        	cout<<max(cnt1,max(cnt2,cnt3))<<endl;
        }
     
        return 0;
    }
    
    

    法二

    #include<bits/stdc++.h>
    using namespace std;
    long long ans,a[100005];
    int main() {
    	int t;
    	scanf("%d",&t);
    	while(t--){
    		int n;
    		long long mx=-1e9;
    		scanf("%d",&n);
    		for(int i=1;i<=n;i++)scanf("%lld",&a[i]),mx=max(mx,a[i]);
    		sort(a+1,a+n+1,[](long long x,long long y){return abs(x)>abs(y);});
    		if(mx<0){
    		    cout<<a[n]*a[n-1]*a[n-2]*a[n-3]*a[n-4]<<'
    ';
    		    continue;
    		}
    		ans=a[1]*a[2]*a[3]*a[4]*a[5];
    		//这是绝对值最大的五个数的乘积
    		/*
    		-3 -2 -1 1 2 3 4 5
    		5 4 3 -3 2 -2 1 -1
    		*/
    		//把前五个绝对值最大的数中的某一个数替换成后边n-5中的某一个数
    		for(int i=6;i<=n;i++)
    		{
    		    for(int j=1;j<=5;j++)
    		    {
    		        long long tmp=a[i];//想要更换的那个数
    		        for(int k=1;k<=5;k++){
    		            if(k!=j)tmp*=a[k];
    		        }
    		        ans=max(ans,tmp);
    		    }
    		}
    		printf("%lld
    ",ans);
    	}
        return 0;
    }
    

    7.CodeForces - 1405 B Array Cancellation

    ( 法一.\ O(N)跑一遍前缀和,如果前缀和小于0,代表必须付出的代价,累计abs(代价),前缀和清空\ 最后输出代价。\ 法二.\ 定义后缀和c[i]=a[i]+a[i+1]+...+a[n]\ 最后有a[0]=a[1]=a[2]=...=a[n]=0,所以有c[n]=c[n-1]=...=c[1]=0; 因为a[i]=c[i]-c[i+1],a[j]=c[j]-c[j+1],当i<j时,尽量让a[i]--,a[j]++\ 就有c[i+1]++,c[j]++;\ 即c[i+1]...c[j]这段连续的数组越大越好.处理后缀和数组,输出最大后缀和就是ans. )

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=1e5+5;
    ll a[maxn];
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            int n;
            cin>>n;
            for(int i=0;i<n;i++)
                cin>>a[i];
            ll ans=0,sum=0;
            for(int i=0;i<n;i++)
            {
                ans+=a[i];
                if(ans<0)
                    sum+=-ans,ans=0;
            }
            cout<<sum<<endl;
        }
        return 0;
    }
    
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    using namespace std;
    #define rep(i,a,n) for(int i=0;i<n;i++)
    #define per(i,a,n) for(int i=n;i>=0;i--)
    #define pb push_back
    #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    
    typedef long long ll;
    const int N=111000;
    ll a[N];
    ll sum;
    int main()
    {
    	IOS;
    	int t;cin>>t;
    	while(t--)
    	{
    	    int n;cin>>n;
    	    ll ans=-1e6;
    	    for(int i=n;i>=1;i--)
    	        cin>>a[i];
    	    for(int i=1;i<=n;i++)
    	    {
    	        sum+=a[i];
    	        ans=max(ans,sum);
    	    }
    	    cout<<ans<<endl;
    	}
    	return 0;
    }
    

    8.CodeForces - 1392 C Omkar and Waterslide

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<cmath>
    using namespace std;
    #define rep(i,a,n) for(int i=0;i<n;i++)
    #define per(i,a,n) for(int i=n;i>=0;i--)
    #define pb push_back
    #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    
    typedef long long ll;
    /*
    思路:(假思路)
    假了,wok,最烦这种想一会发现对不上题。
    如果数组最大最小值相等输出0
    否则使用双指针遍历原始数组
    找到区间[i,j],该区间所有元素的最大值一定小于max,求出区间[i,j]中最小的元素a,
    ans=max-a
    
    别人的思路
    题意:目的:数组不递减,可以让连续的一段区间[l,r],上,各个元素自增1
    10 5 3 7 2 10
    1.让 5 3 7 2 变成10;
    2.让 5 3 变成7 2变成7;
    3.让 3变成5 
    上述操作可以写成
    if(a[i]>a[i+1])
    sum+=a[i]-a[i+1];
    输出sum即为ans
    */
    const int N=2e5+10;
    int a[N];
    int main()
    {
    	IOS;
    	int t;cin>>t;
    	while(t--)
    	{
    	    int n;cin>>n;
    	    for(int i=1;i<=n;i++)
    	        cin>>a[i];
    	    ll sum=0;
    	    for(int i=1;i<n;i++)
    	    {
    	        if(a[i]>a[i+1])
    	            sum+=a[i]-a[i+1];
    	    }
    	    cout<<sum<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    .NETCORE微服务架构--网关篇(Ocelot)
    Hangfire实战--添加DashBoard登录权限
    IIS发布-HTTP谓词限制访问
    基于Dapper的泛型Repository
    .Net Framework JWT验证
    .Net Framework swagger 进阶----头部参数
    .Net Framework下安装api swagger
    ErrorSet
    201907总结
    博客美化
  • 原文地址:https://www.cnblogs.com/forward-985/p/13996676.html
Copyright © 2011-2022 走看看