贪心/暴力/思维专题

牛牛的朋友

题目链接:https://ac.nowcoder.com/acm/problem/21545

这个贪心思路我真的i了 第一次遇到这样的贪心 觉得思路真的很巧妙qwq 所以分享一波

首先对所有的牛排序一波 然后枚举分界点 分界点左边向右移 分界点右边向左移 然后排序 更新其中的最小值

#include<bits/stdc++.h>
using namespace std;
const int maxn = 55;
int a[maxn],b[maxn],minn=0x3f3f3f3f;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int k;
    scanf("%d",&k);
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<=i;j++)
            b[j]=a[j]+k;
        for(int j=i+1;j<=n;j++)
            b[j]=a[j]-k;
        sort(b+1,b+n+1);
        minn=min(minn,b[n]-b[1]);
    }
    printf("%d\n",minn);
}

两条斜线

题目链接:https://ac.nowcoder.com/acm/problem/18951

首先斜率为1或者-1 可以得出 y+x相等或者y-x相等 然后用两个map记录每一对坐标的a[i]-a[j]和a[i]+a[j] 然后枚举所有的map 遍历a[i] 更新最大值

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3+5;
map<int,int> m1,m2;
int x[maxn],y[maxn],maxx,n;
int cut(int k1,int k2)
{
    int cnt=0;
    for(int i=1; i<=n; i++)
    {
        if((x[i]-y[i]==k1)||(x[i]+y[i]==k2))
            cnt++;
    }
    return cnt;
}
int main()
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
        scanf("%d",&x[i]);
    for(int i=1; i<=n; i++)
        scanf("%d",&y[i]);
    for(int i=1; i<=n; i++)
    {
        m1[x[i]-y[i]]++;
        m2[x[i]+y[i]]++;
    }
    map<int,int>::iterator it1,it2;
    for(it1=m1.begin(); it1!=m1.end(); it1++)
    {
        for(it2=m2.begin(); it2!=m2.end(); it2++)
        {
            maxx=max(maxx,cut(it1->first,it2->first));
        }
    }
    printf("%d\n",maxx);
}

Odd Sum Segments

题目链接:http://codeforces.com/contest/1196/problem/B

我们先可以进行判断,假设数组的和为sum,要分成k个,那么当sum为奇数 k为偶数 或者sum为偶数 k为奇数时,都不满足。记录数组元素中奇数的个数,每遇到一次奇数就输出(因为每一个区间只有一个奇数,奇数前面都是偶数,所以和是奇数),但是这个时候还要判断k是否<=奇数个数,因为不管把哪个奇数加到已经分好的区间,区间和都会变成偶数

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 2e5+10;
int a[maxn];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,k,num=0,cnt=0;
        ll sum=0;
        scanf("%d %d",&n,&k);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            sum+=a[i];
            if(a[i]%2!=0)
                num++;
        }
        if(k>num||(sum%2)!=(k%2))
        {
            puts("NO");
            continue;
        }
        puts("YES");
        for(int i=1;i<=n;i++)
        {
            if(cnt==k-1) break;
            if(a[i]%2!=0) cnt++,printf("%d ",i);
        }
        printf("%d\n",n);
    }
}

珂朵莉与宇宙

题目链接:https://ac.nowcoder.com/acm/problem/14600

首先根据题意

sum[r]-sum[l-1]=c^2

sum[r]-c^2=sum[l-1]
所以我们只需要枚举右边界和c,然后再枚举过程中维护每一个前缀和的值

当a[i]本身是一个完全平方数,他本身就是一个区间 所以num[0]=1

/*Today you do things people will not do,
tomorrow you will do things people can not do.*/
 
#include<bits/stdc++.h>
#define ll long long
#define lson l,m,cnt<<1
#define rson m+1,r,cnt<<1|1
//priority_queue <int,vector<int>,greater<int> > Q;//优先队列递增
//priority_queue<int>Q;//递减
using namespace std;
const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-6;
int sum[maxn],num[maxn*10];
int main()
{
    int n,i,x;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x;
        sum[i]=x+sum[i-1];
    }
    ll ans=0;
    num[0]++;
    //sum[r]-c^2=sum[l-1];
    for(int i=1;i<=n;i++) //枚举右端点
    {
        for(int p=0;p*p<=sum[i];p++) //枚举p
        {
            ans+=num[sum[i]-p*p];
        }
        num[sum[i]]++;
    }
    printf("%lld\n",ans);
}

凌波微步

题目链接:https://ac.nowcoder.com/acm/problem/14346

其实是一道对STL的应用,因为题目没说一定是从左到右,所以可以随便跳,所以直接排序+去重就可以了

/**Today you do things people will not do,
tomorrow you will do things people can not do.**/
 
#include<bits/stdc++.h>
#define ll long long
#define lson l,m,cnt<<1
#define rson m+1,r,cnt<<1|1
//priority_queue <int,vector<int>,greater<int> > Q;//优先队列递增
//priority_queue<int>Q;//递减
using namespace std;
const int maxn = 5e5+10;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-6;
int a[maxn];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        printf("%d\n",unique(a+1,a+n+1)-a-1);
    }
}

Chessboard

题目链接:http://codeforces.com/problemset/problem/961/C

我们可以先处理首位是0 首位是1的情况 然后因为只有四种情况 可以暴力匹配

/*Today you do things people will not do,
tomorrow you will do things people can not do.*/
 
#include<bits/stdc++.h>
#define ll long long
#define lson l,m,cnt<<1
#define rson m+1,r,cnt<<1|1
//priority_queue <int,vector<int>,greater<int> > Q;//优先队列递增
//priority_queue<int>Q;//递减
using namespace std;
const int maxn = 1e2+10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
const double PI = acos(-1.0);
const double eps = 1e-6;
int mp1[2*maxn][2*maxn];
int mp0[2*maxn][2*maxn];
int mp[2*maxn][2*maxn][10];
int cut,ans=INF;
int main()
{
    int t;
    scanf("%d",&t);
    for(int k=1; k<=4; k++)
    {
        for(int i=1; i<=t; i++)
        {
            for(int j=1; j<=t; j++)
            {
                scanf("%1d",&mp[i][j][k]);
            }
        }
    }
    //为1开头
    for(int i=1; i<=t; i++)
    {
        for(int j=1; j<=t; j++)
        {
            if((i+j)%2==0)
                mp1[i][j]=1;
            else
                mp1[i][j]=0;
        }
    }
    //为0开头
    for(int i=1; i<=t; i++)
    {
        for(int j=1; j<=t; j++)
        {
            if((i+j)%2==0)
                mp0[i][j]=0;
            else
                mp0[i][j]=1;
        }
    }
    for(int i=1; i<=t; i++)
    {
        for(int j=1; j<=t; j++)
        {
            if(mp[i][j][1]!=mp1[i][j])
                cut++;
            if(mp[i][j][2]!=mp1[i][j])
                cut++;
            if(mp[i][j][3]!=mp0[i][j])
                cut++;
            if(mp[i][j][4]!=mp0[i][j])
                cut++;
        }
    }
    ans=min(cut,ans);
    cut=0;
    for(int i=1; i<=t; i++)
    {
        for(int j=1; j<=t; j++)
        {
            if(mp[i][j][1]!=mp1[i][j])
                cut++;
            if(mp[i][j][2]!=mp0[i][j])
                cut++;
            if(mp[i][j][3]!=mp1[i][j])
                cut++;
            if(mp[i][j][4]!=mp0[i][j])
                cut++;
        }
    }
    ans=min(cut,ans);
    cut=0;
    for(int i=1; i<=t; i++)
    {
        for(int j=1; j<=t; j++)
        {
            if(mp[i][j][1]!=mp0[i][j])
                cut++;
            if(mp[i][j][2]!=mp1[i][j])
                cut++;
            if(mp[i][j][3]!=mp0[i][j])
                cut++;
            if(mp[i][j][4]!=mp1[i][j])
                cut++;
        }
    }
    ans=min(cut,ans);
    cut=0;
    for(int i=1; i<=t; i++)
    {
        for(int j=1; j<=t; j++)
        {
            if(mp[i][j][1]!=mp0[i][j])
                cut++;
            if(mp[i][j][2]!=mp0[i][j])
                cut++;
            if(mp[i][j][3]!=mp1[i][j])
                cut++;
            if(mp[i][j][4]!=mp1[i][j])
                cut++;
        }
    }
    ans=min(cut,ans);
    cut=0;
    for(int i=1; i<=t; i++)
    {
        for(int j=1; j<=t; j++)
        {
            if(mp[i][j][1]!=mp0[i][j])
                cut++;
            if(mp[i][j][2]!=mp1[i][j])
                cut++;
            if(mp[i][j][3]!=mp1[i][j])
                cut++;
            if(mp[i][j][4]!=mp0[i][j])
                cut++;
        }
    }
    ans=min(cut,ans);
    cut=0;
    for(int i=1; i<=t; i++)
    {
        for(int j=1; j<=t; j++)
        {
            if(mp[i][j][1]!=mp1[i][j])
                cut++;
            if(mp[i][j][2]!=mp0[i][j])
                cut++;
            if(mp[i][j][3]!=mp0[i][j])
                cut++;
            if(mp[i][j][4]!=mp1[i][j])
                cut++;
        }
    }
    ans=min(cut,ans);
    printf("%d\n",ans);
}

  

扫描二维码关注公众号,回复: 6976501 查看本文章

猜你喜欢

转载自www.cnblogs.com/CSUSTJCC/p/11318467.html