概述
A、Ace of Aces(ZOJ 3869)
有n个人投票,求出来票数最多的那个人的id。如果多个人票数一样,输出“Nobody”。
#include <stdio.h>
#include <string.h>
#define N 1010
int num[N];
int main(void)
{
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
memset(num, 0, sizeof(num));
for (int i = 0; i <n ;++i) {
int x;
scanf("%d", &x);
num[x]++;
}
int pos = 1;
int flag = 0;
for (int i = 1; i <=1000; ++i) {
if (num[pos] < num[i]) {
pos = i;
}
}
int m = 0;
for (int i = 1; i <= 1000; ++i) {
if (num[i] == num[pos]) {
++m;
}
}
if (m == 1) {
printf("%dn", pos);
} else {
printf("Nobodyn");
}
}
return 0;
}
B、Team Formation(ZOJ 3870)
有n个数,从这n个数中任选两个数a,b,问有多少组数满足a^b > max(a, b)。
我们假定有两个数x,y。其中1
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 100010
typedef long long ll;
// mp[i], number >= 2^i && < 2^(i+1)
ll num[N], mp[40];
ll get2(ll n)
{
int res = 0;
while (n) {
n >>= 1;
++res;
}
return res - 1;
}
int main(void)
{
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i) {
scanf("%d", &num[i]);
}
sort(num, num + n);
memset(mp, 0, sizeof(mp));
for (int i = 0; i < n; ++i) {
int idx = get2(num[i]);
mp[idx]++;
}
ll ans = 0;
for (int i = 0; i < n; ++i) {
int a = num[i];
int m = 0;
while (a) {
if ((a & 1) == 0) {
ans += mp[m];
//printf("%d...n", mp[m]);
}
a >>= 1;
++m;
}
}
printf("%dn", ans);
}
return 0;
}
D、Beauty of Array(ZOJ 3872)
定义了一个数组的美丽值,就是数组中不同数值加起来的和。让求的是给定一个数组中所有连续的子数组的美丽值的和。我们用dp[i]表示前i个数连续字数组的美丽值的和。
每加进来一个数,dp[i+1]要在加上dp[i]的基础上额外加上某些num[i + 1],这取决于之前最后一次出现num[i + 1]的位置,用另外一个组数记录这个位置就行了。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
#define N 100010
ll num[N], dp[N];
int vis[1000010];
int main(void)
{
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%lld", &num[i]);
}
memset(vis, 0, sizeof(vis));
memset(dp, 0, sizeof(dp));
dp[1] = num[1];
ll sum = num[1];
vis[num[1]] = 1;
for (int i = 2; i <= n; ++i) {
dp[i] = dp[i - 1];
// 两种情况可以合成一种
//if (!vis[num[i]]) {
// vis[num[i]] = i;
// dp[i] += i * num[i];
//} else {
dp[i] += (i - vis[num[i]]) * num[i];
vis[num[i]] = i;
//}
sum += dp[i];
}
printf("%lldn", sum);
}
return 0;
}
G、Lunch Time(ZOJ 3875)
简单的求中位数的,不过偶数的情况是取贵的那一个菜。因为有三种菜,计算三次就行了。
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 110
struct Node {
char name[N];
int val;
void input(void)
{
scanf("%s%d", name, &val);
}
}x[N], y[N], z[N];
char ans[N * 2];
int cnt;
bool cmp(Node u, Node v)
{
return u.val < v.val;
}
int f(Node node[], int n)
{
//printf("%d %d %s...n", n / 2, node[n / 2].val, node[n / 2].name);
++cnt;
strcat(ans, node[n / 2].name);
if (cnt < 3) {
strcat(ans, " ");
}
return node[n / 2].val;
}
int main(void)
{
int t;
scanf("%d", &t);
while (t--) {
int s, m, d;
scanf("%d%d%d", &s, &m, &d);
ans[0] = '