题目来源:http://codeforces.com/gym/100257
2013-2014 ACM-ICPC, NEERC, Moscow Subregional Contest
A
题意:给你N个点,以及每个点的钥匙数,从A点走到B点需要消耗1把A型钥匙,问你最多能走出多少个三角形。
解法:用优先队列维护,优先队列中放的是所有的非零钥匙数,一个三角形只需要(1,1,1)或者(0,1,2)这两种之一就可以形成。
先对(0,1,2)进行处理,每次取出最大的两个数,更新答案和这两个数,知道最大的数小于2为止。
然后对(1,1,1)进行类似处理,每次取出三个1,更新答案并且把这三个1变为0。
这两部分算完后就是答案。
/* UESTC Summer Training #18 Div.2. Problem A. */
#include <bits/stdc++.h>
#include <cstdio>
#include <queue>
#define MIN(a, b) ( ((a)<(b))?(a):(b) )
#define MAXN 10024
using namespace std;
int N = 0;
int nfields = 0;
priority_queue<int> keys;
int main(void)
{
int i = 0;
int t = 0;
int k[3] = {0};
scanf("%d", &N);
while(!keys.empty())
keys.pop();
for(i = 0;i < N;++i)
{
scanf("%d", &t);
keys.push(t);
}
if(N < 3)
{
puts("0");
}
else
{
while(1)
{
k[0] = keys.top();
if(k[0] < 2)
break;
if(keys.size() < 2)
break;
for(i = 0;i < 2;++i)
{
k[i] = keys.top();
keys.pop();
}
int s = min(k[1],k[0] / 2);
nfields += s;
k[0] -= 2 * s;
k[1] -= s;
//printf("k0 = %d k1 = %d\n",k[0],k[1]);
if(k[0] != 0)
keys.push(k[0]);
if(k[1] != 0)
keys.push(k[1]);
//printf(" %d\n", nfields);
}
//printf("%d\n",keys.size());
while( keys.size() > 2 )
{
for(i = 0;i < 3;++i)
{
k[i] = keys.top();
keys.pop();
}
nfields++;
for(i = 0;i < 3;++i)
{
if( (--k[i]) > 0 )
keys.push(k[i]);
}
//printf(" %d\n", nfields);
}
printf("%d\n", nfields);
}
return 0;
}
B
题意:给一个16进制数,让你找出16进制数中比这个数大且尽可能小且每一位都不相同的数是多少。
/* UESTC Summer Training #18 Div.2. Problem B. */
#include <stdio.h>
#include <string.h>
const char digit[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D',
'E','F'};
char origin[32] = {'0',0};
int l = 0;
int inc(int i)
{
int count = 0;
while( i >= 0 )
{
if( 'F' == origin[i] )
{
count++;
origin[i] = '0';
i--;
}
else
{
if( '9' == origin[i] )
origin[i] = 'A';
else
origin[i]++;
break;
}
}
return count;
}
void handle(int togenerate)
{
int i = 0;
int used[128] = {0};
int nused = 0;
for(i = (origin[0]>'0')?(0):(1);i < togenerate;++i)
if( 1 == used[origin[i]] )
{
handle(i+1-inc(i));
nused++;
break;
}
else
used[origin[i]] = 1;
if( 0 == nused )
if( togenerate < l )
{
int count = 0;
for(i = 0;i < 16 && count < (l-togenerate);++i)
if( 0 == used[digit[i]] )
{
origin[togenerate+count] = digit[i];
++count;
}
}
}
int main(void)
{
scanf("%s", origin+1);
l = strlen(origin);
inc(l-1);
handle(l);
printf("%s\n", (origin[0]>'0')?(origin):(origin+1));
return 0;
}
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <string>
typedef unsigned long long ull;
typedef long long ll;
char s[111];
int n;
int go(int pos) {
if(pos==n) return 1;
int i;
for(i=0;i<pos;i++) if(s[i] == s[pos]) break;
if(i==pos && go(pos+1)) return 1;
for(char c=s[pos]+1;c!='G';c++) {
if(c==('9'+1)) c='A';
s[pos]=c;
for(i=0;i<pos;i++) if(s[i] == c) break;
if(i != pos) continue;
for(int j=pos+1;j<n;j++) s[j]='0';
if(go(pos+1)) return 1;
}
return 0;
}
int main() {
ull x;
while(scanf("%llx", &x) != EOF) {
x++;
sprintf(s, "%llx", x);
n = strlen(s);
for(int i=0;i<n;i++) s[i] = toupper(s[i]);
if(go(0)) printf("%s\n", s);
else {
memset(s, '0', sizeof(s));
s[0]='1';
n++;
go(0);
s[n]='\0';
printf("%s\n", s);
}
}
return 0;
}
F
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <string>
#define ll long long
using namespace std;
typedef pair<int, int> PII;
int a[2003], b[2003];
int dp[2003];
int n;
int main() {
int i, j;
scanf("%d", &n);
for (i = 1; i <= n; i++) {
int x, y;
char ch;
scanf("%d:%d %c", &x, &y, &ch);
a[i] = x * 60 + y;
b[i] = (ch == 'U');
}
int cnt = 0, last = -1e9;
bool flag = 0;
int pay = 0;
for (i = 1; i <= n; i++) {
if (a[i] - last <= 90) {
if (b[i] == 0) {
if (!pay) {
cnt += 26;
pay = 26;
} else {
cnt += 44 - pay;
pay = 44;
}
} else if (!flag) {
flag = 1;
if (!pay) {
cnt += 28;
pay = 28;
} else {
cnt += 44 - pay;
pay = 44;
}
} else {
last = a[i];
cnt += 28;
pay = 28;
}
} else {
last = a[i];
if (b[i] == 0) {
cnt += 26;
pay = 26;
flag =0;
} else {
flag = 1;
cnt += 28;
pay = 28;
}
}
//printf("cnt = %d ", cnt);
}
printf("%d ", cnt);
for (i = 0; i <= n; i++)
dp[i] = 1e9;
dp[0] = 0;
a[0] = -1e9;
for (i = 0; i < n; i++) {
dp[i + 1] = min(dp[i + 1], dp[i] + (b[i + 1] == 1 ? 28 : 26));
// printf("%d\n", dp[i+1]);
int cnt = 0;
j = i + 1;
int cur = a[i + 1];
while (j <= n && a[j] - cur <= 90) {
if (b[j] == 1)
cnt++;
if (cnt >= 2)
break;
j++;
}
j--;
dp[j] = min(dp[j], dp[i] + 44);
}
// for(i = 1; i <= n; i++)
// printf("%d~~~ ", dp[i]);
printf("%d\n", dp[n]);
return 0;
}
H
#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define INF 0x3f3f3f3f
#define eps 1e-6
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9 + 7;
using namespace std;
int fun(int a,int c,int b)
{
if(a >= b && b >= c || a <= b && b <= c)
return 1;
return 0;
}
int main()
{
ios_base::sync_with_stdio(0);cin.tie(0);
int a[3],b[3];
cin >> a[0] >> b[0];
cin >> a[1] >> b[1];
cin >> a[2] >> b[2];
int ok = 0;
if(fun(a[0],a[1],a[2]) && fun(b[0],b[1],b[2]))
ok = 1;
if(ok)
puts("Yes");
else
puts("No");
return 0;
}
I
题意:给你N个集合,并且给出这N个集合两两之间的交集,问你是否能构造出这样的N个集合。
解法:用set模拟即可。
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define eps 1e-6
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 25 * 1E8;
using namespace std;
set <int> s[205];
set <int> :: iterator it;
int a[205][205];
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
ios_base::sync_with_stdio(0);cin.tie(0);
int N;
cin >> N;
memset(a,0,sizeof(a));
int x,y,k,p;
for(int i = 1;i <= (N * (N - 1) / 2);i++)
{
cin >> x >> y >> k;
a[x][y] = a[y][x] = k;
for(int i = 0;i < k;i++)
{
cin >> p;
s[x].insert(p);
s[y].insert(p);
}
}
int ok = 1;
for(int i = 1;i <= N;i++)
for(int j = i + 1;j <= N;j++){
int num = 0;
for(it = s[i].begin();it != s[i].end();it++)
if(s[j].find(*it) != s[j].end())
num++;
if(num != a[i][j])
{
ok = 0;
break;
}
}
if(ok)
{
puts("Yes");
for(int i = 1;i <= N;i++)
{
int q = s[i].size();
printf("%d",q);
for(it = s[i].begin();it != s[i].end();it++)
printf(" %d",*it);
puts("");
}
}
else
puts("No");
return 0;
}
K
#include <cstdio>
#include <algorithm>
int ans[200000], q[200000];
int main() {
int a, b, c, x, y, n, k, l = 0;
scanf("%d%d%d%d%d%d%d", &n, &k, &x, &y, &a, &b, &c);
int tx = x, ty = y, tz;
for (int i = 0; i < n; i++) {
tz = a*tx+b*ty+c&(1<<31)-1;
tx = ty, ty = tz;
if (!(i%20)) {
if (l >= k && tz <= -q[0])
continue;
if (l >= k)
std::pop_heap(q, q+l), l--;
q[l++] = -tz;
std::push_heap(q, q+l);
}
}
tx = x, ty = y;
for (int i = 0; i < n; i++) {
tz = a*tx+b*ty+c&(1<<31)-1;
tx = ty, ty = tz;
if (i%20) {
if (l >= k && tz <= -q[0])
continue;
if (l >= k)
std::pop_heap(q, q+l), l--;
q[l++] = -tz;
std::push_heap(q, q+l);
}
}
for (int i = 0; i < k; i++)
ans[k-i-1] = -q[0], std::pop_heap(q, q+l), l--;
printf("%d", ans[0]);
for (int i = 1; i < k; i++)
printf(" %d", ans[i]);
puts("");
return 0;
}