cf练手day3

http://codeforces.com/contest/1130/problem/A
题意:给出n个数,找一个d,使得这n个数除以d之后,有不少于[n/2]个正数,如果找不到这样的d,就输出0。

做法:求[n/2]直接就(n+1)/2,正数除以一个正数还是正数,负数除以一个负数是正数,所以统计数列中正数、负数分别有多少,取多的那个,如果是正数多就输出1,如果是负数多就输出-1,如果多的那个都比[n/2]要小,就表明找不到这样的d,输出0。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 105;
int a[maxn];
int main()
{
    int n;
    scanf("%d",&n);
    int num1=0,num2=0;//num1代表负数个数 num2代表正数个数
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if(a[i] < 0)
            num1++;
        if(a[i] > 0)
            num2++;
    }
    int num = (n + 1) / 2;
    int ans = max(num1,num2);
    if(ans < num)
        printf("0");
    else
    {
        if(ans == num1)
        printf("-1");
        else
        printf("1");
    }
}

http://codeforces.com/contest/1130/problem/B
题意:有2*n间蛋糕店,每间蛋糕店提供size为a[i]的蛋糕,保证size为1-n的蛋糕有且仅有两间店在卖。两个人买蛋糕,每个人都必须从size为1的蛋糕开始买,直到买到size为n的蛋糕。问两个人总步数最小值。

做法:把蛋糕店排序,卖size小的店排前面,size一样则编号为小的店排前面,两个人,一个人总是挑排前面的买,另一个总是挑排后面的买。
(又wa又re真是。。。re是一开始把maxn定义为n的最大值,但是蛋糕店有2*n间,wa是没开ll)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn = 200005;

struct node
{
    ll id,sz;//蛋糕店的编号,卖的蛋糕的size
}a[maxn];

bool cmp(node x,node y)
{
    if(x.sz != y.sz)
        return x.sz < y.sz;
    else
        return x.id < y.id;
}

int main()
{
    int n;
    memset(a,0ll,sizeof(a));
    scanf("%d",&n);
    for(ll i=1; i<=2*n; i++)
    {
        cin>>a[i].sz;
        a[i].id = i;
    }
    sort(a+1,a+1+2*n,cmp);
    ll s = 0,d = 0,ls = 0,ld = 0;//s记录Sasha上一个点走到哪,d同理,ls记录Sasha目前走了多少步,ld同理
    for(ll i=1; i<=2*n; i++)
    {
        if(a[s].sz < a[i].sz)
        {
            ls += llabs(a[i].id - a[s].id);
            s = i;
        }
        else
        {
            if(a[d].sz < a[i].sz)
            {
                ld += llabs(a[i].id - a[d].id);
                d = i;
            }
        }
    }
    cout<<ld+ls-2;//减2是因为一开始假设两个人在原点,但是其实两个人在(1,0)
}

http://codeforces.com/contest/1138/problem/C
题意:给一个n*m的矩阵,要求以每个点为中心点,对它所在的行列进行离散化,求以每个点为中心的十字上面最大的数为多少。

做法:先对所有行、列分别离散化,每一个点在行列都离散化后的值等于max(它在该行中的大小,它在该列中的大小),答案是该点离散化后的值加上max(行元素个数-它在行中的位置,列元素个数-它在列中的位置)。

#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
#include <set>
using namespace std;
const int maxn = 1005;
int a[maxn][maxn],cp[maxn][maxn],b[maxn][maxn];//cp存储原矩阵 a存储原矩阵中的每一行 b存储原矩阵中的每一列
int row[maxn],col[maxn];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            scanf("%d",&a[i][j]);
            cp[i][j] = b[j][i] = a[i][j];
        }
    }
    for(int i=1; i<=n; i++)//对每一行进行离散
    {
        sort(a[i] + 1,a[i] + 1 + m);
        row[i] = unique(a[i] + 1,a[i] + 1 + m) - (a[i] + 1);
    }
    for(int i=1; i<=m; i++)//对每一列进行离散
    {
        sort(b[i] + 1,b[i] + 1 + n);
        col[i] = unique(b[i] + 1,b[i] + 1 + n) - (b[i] + 1);
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            int num1 = lower_bound(a[i] + 1,a[i] + 1 + row[i],cp[i][j]) - a[i];//该数字在该行中第几大
            int num2 = lower_bound(b[j] + 1,b[j] + 1 + col[j],cp[i][j]) - b[j];//该数字在该列中第几大
            int num = max(num1,num2);//以行列中较大的那个值作为它离散后的值
            printf("%d ",num + max(row[i] - num1,col[j] - num2));//它的值加上max(行中比它大的数的数量,列中比它大的数的数量)
        }
        printf("\n");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值