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");
}
}