UESTC 2016 Summer Training #18 Div.2(未完待续)

题目来源: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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值