A. Cancel the Trains(A~C)

本文探讨了编程竞赛中的三种题目类型:A题考察消除相同编号火车,B题涉及序列操作达到全相同状态,C题涉及矩阵内三角形最大面积。针对每种题目,分别给出了高效解题思路,包括如何优化操作次数和寻找最大面积的方法。
摘要由CSDN通过智能技术生成

题目传送门

A. Cancel the Trains

思路

  1. 如果横竖方向的两个火车编号相同一定会相撞,编号不同不想撞,因此当横竖方向的两个火车编号相同时需要去掉其中任意一个火车
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <string>
#include <string>
#include <map>
#include <bitset>
#include <vector>
void fre() { system("clear"), freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { system("clear"), freopen("A.txt", "r", stdin);}
void Run(int x = 0) {     
#ifdef ACM  //宏定义免注释 freopen
    if(! x) fre(); else Fre();
#endif
}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define db double
#define ll long long
#define ull unsigned long long
#define Pir pair<ll, ll>
#define m_p make_pair
#define for_(i, s, e) for(ll i = (ll)(s); i <= (ll)(e); i ++)
#define rep_(i, e, s) for(ll i = (ll)(e); i >= (ll)(s); i --)
#define memset(a, b, c) memset(a, (int)b, c);
#define size() size() * 1LL
#define sc scanf
#define pr printf
#define sd(a) scanf("%lld", &a)
#define ss(a) scanf("%s", a)
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define esp 1e-7
#define mod (ll)(1e9 + 7)
using namespace std;
/*=========================ACMer===========================*/

ll ar[105];


int main()
{
    /* Run(); */
    ll T; sd(T);
    while(T --)
    {
        memset(ar, 0, sizeof ar);
        ll n, m;
        sc("%lld %lld", &n, &m);
        for_(i, 1, n)
        {
            ll t; sd(t);
            ar[t] = 1;
        }
        ll ans = 0;
        for_(i, 1, m)
        {
            ll t; sd(t);
            if(ar[t]) ans ++;
        }
        
        pr("%lld\n", ans);
    }



    return 0;
}

B. Suffix Operations

题意

  1. 给我们一个有 n 个元素的序列 ar,我们可以对这个序列的后缀进行操作,
  2. 对于一次操作,我们可以选择 ar 的任意一个后缀,将其中的所有元素 + 1 或 - 1,
  3. 问我最少使用多少次操作是 ar 中的序列的元素变的全部相同。

思路

  1. 当我先不考虑要改变的那个数的时候,我们要要想把整个序列变的有序,就只能使用一些操作先把 ar [n] 变成 ar [n-1] 相同,之后再把 ar [n] 与 ar [n-1] 变的与 ar [n-2] 相同… 如果中间跳过某个元素,我们造成使用更多次操作,
  2. 当我先不考虑要改变的那个数的时候, 我我们把整个序列元素变的全部相同需要的次数是恒定的设为 sum,
  3. 当我们考虑修改某个元素的时候,假设修改的元素是 ar [x] (x>1 && x < n)这个时候我们减少的操作次数为 cnt= abs (a [x] - a [x + 1) + abs (a [x] - a [x-1]) - abs (a [x-1] - a [x+1]), 那么我们可以枚举所有的可能的 x,的到最大减少次数 mxn_cnt,
  4. 那答案是 sum - mxn_cnt.
  5. 最后在特判一下 首元素 a [1] 变成 a [2] 时候的答案,
  6. 最后在特判一下 尾元素 a [n] 变成 a [n-1] 时候的答案,
  7. 维护一下所有的答案的最大值,就行了
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <string>
#include <string>
#include <map>
#include <bitset>
#include <vector>
void fre() { system("clear"), freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { system("clear"), freopen("A.txt", "r", stdin);}
void Run(int x = 0) {     
#ifdef ACM  //宏定义免注释 freopen
    if(! x) fre(); else Fre();
#endif
}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define db double
#define ll long long
#define ull unsigned long long
#define Pir pair<ll, ll>
#define m_p make_pair
#define for_(i, s, e) for(ll i = (ll)(s); i <= (ll)(e); i ++)
#define rep_(i, e, s) for(ll i = (ll)(e); i >= (ll)(s); i --)
#define memset(a, b, c) memset(a, (int)b, c);
#define size() size() * 1LL
#define sc scanf
#define pr printf
#define sd(a) scanf("%lld", &a)
#define ss(a) scanf("%s", a)
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define esp 1e-7
#define mod (ll)(1e9 + 7)
using namespace std;
/*=========================ACMer===========================*/
const ll mxn = 2e5 + 10;
ll ar[mxn];
ll br[mxn];
ll cr[mxn];
vector<Pir> v;

ll sov(ll ar[], ll n)
{
    ll t = ar[n], ans = 0;
    rep_(i, n - 1, 1)
    {
        if(ar[i] == t)
            continue;
        else
        {
            ans += abs(ar[i] - t);
            t = ar[i];
        }
    }
    return ans;
}

int main()
{
    Run();
    ll T; sd(T);
    while(T --)
    {
        v.clear();
        ll n; sd(n);
        for_(i, 1, n)
        {
            sd(ar[i]);
            br[i] = ar[i];
        }

        if(n == 1 || n == 2)
        {
            pr("0\n");
            continue;
        }

        ll ans = INF;

        //第一种修改最右边的元素
        br[n] = br[n - 1];
        ans = min(ans, sov(br, n));
        br[n] = ar[n];
        //修改最左边的情况
        br[1] = br[2];
        ans = min(ans, sov(br, n));
        br[1] = ar[1];


        ar[0] = ar[1];
        ar[n + 1] = ar[n];
        Pir id = m_p(-INF, 1);
        for_(i, 2, n - 1)
        {
            if((ar[i] >= ar[i + 1] && ar[i] >= ar[i - 1]) || (ar[i] <= ar[i + 1] && ar[i] <= ar[i - 1]))
            {
                cr[i] = abs(ar[i] - ar[i + 1]) + abs(ar[i] - ar[i - 1]) - abs(ar[i - 1] - ar[i + 1]);
                if(id.fi < cr[i])
                {
                    id.fi = cr[i];
                    id.se = i;
                }
            }
        }

        //修改中间的情况
        br[id.se] = br[id.se + 1];
        ans = min(ans, sov(br, n));
        br[id.se] = ar[id.se];

        pr("%lld\n", ans);

    }

    return 0;
}


C. Triangles

题意

  1. 给我们一个 n*n 的表格,表格中填着 0~9 之间的数字,对于每种数字,我需要从同种数字中选择三个点,使这三个点形成的三角形面积最大,形成的三角形至少需要有一条边平行于坐标轴,
  2. 在选择的点的时候我们可以让表格中的任意一个数字变成当前的种类的数字,对于每种数组输出构成的最大面积。

思路

  1. 这一题是暴力枚举,
  2. 我们要看透一点,任选表格中的同种数字的两个,形成一条边,剩下的我们我一定可以在靠近边界的格子上找一个格子点,使这个点与其他两个点中的一个形成一条平行边,,,,,,
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <string>
#include <string>
#include <map>
#include <bitset>
#include <vector>
void fre() { system("clear"), freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
void Fre() { system("clear"), freopen("A.txt", "r", stdin);}
void Run(int x = 0) {     
#ifdef ACM  //宏定义免注释 freopen
    if(! x) fre(); else Fre();
#endif
}
#define ios ios::sync_with_stdio(false)
#define Pi acos(-1)
#define pb push_back
#define fi first
#define se second
#define db double
#define ll long long
#define ull unsigned long long
#define Pir pair<ll, ll>
#define m_p make_pair
#define for_(i, s, e) for(ll i = (ll)(s); i <= (ll)(e); i ++)
#define rep_(i, e, s) for(ll i = (ll)(e); i >= (ll)(s); i --)
#define memset(a, b, c) memset(a, (int)b, c);
#define size() size() * 1LL
#define sc scanf
#define pr printf
#define sd(a) scanf("%lld", &a)
#define ss(a) scanf("%s", a)
#define inf 0x3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define esp 1e-7
#define mod (ll)(1e9 + 7)
using namespace std;
/*=========================ACMer===========================*/
const ll mxn = 15;
const ll N = 2e3 + 10;
ll mxx[mxn], mnx[mxn];
ll mxy[mxn], mny[mxn];
ll ans[mxn];
ll ar[N][N];

void init()
{
    memset(mxx, 0, sizeof mxx);
    memset(mxy, 0, sizeof mxy);
    memset(mnx, INF, sizeof mnx);
    memset(mny, INF, sizeof mny);
    memset(ans, 0, sizeof ans);
}


int main()
{
    Run();
    ll T; sd(T);
    while(T --)
    {
        init();
        ll n; sd(n);
        for_(i, 1, n)
        {
            for_(j, 1, n)
            {
                sc("%1lld", &ar[i][j]);
                ll t = ar[i][j];
                mxx[t] = max(mxx[t], i);
                mnx[t] = min(mnx[t], i);
                mxy[t] = max(mxy[t], j);
                mny[t] = min(mny[t], j);
            }
        }
        for_(i, 1, n)
        {
            for_(j, 1, n)
            {
                ll t = ar[i][j];
                ans[t] = max(ans[t], abs(mxx[t] - i) * max(j - 1, n - j));
                ans[t] = max(ans[t], abs(mnx[t] - i) * max(j - 1, n - j));
                ans[t] = max(ans[t], abs(mxy[t] - j) * max(i - 1, n - i));
                ans[t] = max(ans[t], abs(mny[t] - j) * max(i - 1, n - i));
            }
        }

        for_(i, 0, 9) pr("%lld ", ans[i]);
        pr("\n");
    }
    



    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值