2017ACM/ICPC亚洲区沈阳站【solved:6 / 13】

F-hdu 6222 Heron and His Triangle(找规律)

题意:让你找这样的一个三角形,三条边为t,t-1,t+1,并且面积为整数,最后满足t大于等于n。3w组样例, n1e30
思路:打表找规律。

import java.util.*;
import java.math.BigInteger;

public class Main
{
    public static void main(String[] args)
    {
        BigInteger f[] = new BigInteger[105];
        BigInteger four = new BigInteger("4"); 
        BigInteger onefour = new BigInteger("14");
        f[1] = four;
        f[2] = onefour;
        for(int i = 3; i <= 100; i++)    f[i] = f[i - 1].multiply(four).subtract(f[i - 2]);

        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        for(int i = 0; i < T; i++)
        {
            BigInteger n;
            n = in.nextBigInteger();            
            for(int j = 1; j <= 100; j++)
            {
                if(f[j].compareTo(n) >= 0)
                {
                    System.out.println(f[j]);
                    break;
                }
            }
        }
    }
}

G-hdu 6223 Infinite Fraction Path

题意:给你n个点的价值,点记为0到n-1,然后每个点i
下一步移动到点(i*i+1)%n,如果n=5,且每次经过的点的价值依次为5,6,7,8,9,则这条路径的价值定义为56789,问你长度为n的路径的价值最大是多少。 n150000
思路:先机巧的打个表,看看i*i+1这个过程,发现点的数量衰减的非常快,好像四五次就衰减到两百的数量级了,所以大胆暴力维护即可。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 150000 + 5;
int d[maxn];
char s[maxn], ans[maxn];
int calc(long long i, int n)
{
    return (i * i + 1) % n;
}
int main()
{
    int n, T;
    scanf("%d", &T);
    for(int cas = 1; cas <= T; cas++)
    {
        scanf("%d", &n);
        scanf("%s", s);
        for(int i = 0; i < n; i++)  d[i] = s[i] - '0';
        set<int>vec;
        for(int i = 0; i < n; i++)  vec.insert(i);
        vector<int>val;
        for(int lv = 1; lv <= n; lv++)
        {
            int mx = -1;
            for(auto o : vec)   mx = max(mx, d[o]);
            set<int>temp;
            for(auto o : vec)
            {
                if(d[o] == mx)  temp.insert(calc(o, n));
            }
            vec = temp;
            val.push_back(mx);
        }
        string str = "";
        for(auto o : val) str += o + '0';
        const char* p = str.c_str();
        printf("Case #%d: %s\n", cas, p);
    }
    return 0;
}

I-hdu 6225 Little Boxes

import java.util.*;
import java.math.BigInteger;

public class Main
{
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int T = in.nextInt();
        for(int i = 0; i < T; i++)
        {
            BigInteger a, b, c, d;
            a = in.nextBigInteger();
            b = in.nextBigInteger();
            c = in.nextBigInteger();
            d = in.nextBigInteger();
            a = a.add(b);
            a = a.add(c);
            a = a.add(d);
            System.out.println(a);
        }
    }
}

K-hdu 6227 Rabbits(贪心)

题意:有n只兔子分别占据不同的位置,任意一只兔子可以插入任意两只兔子的之间,但要求两只兔子之间要有空位,求这样的移动次数最多能够有多少?
思路:显然把最左端或者最右端的兔子尽量少的往里放一步的时候,移动次数浪费的最少,放一步以后显然剩下的空位都可以移动

#include <bits/stdc++.h>
using namespace std;
const int maxn = 500 + 5;
int a[maxn], blank[maxn];
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
        int tot = 0;
        for(int i = 1; i + 1 <= n; i++)  blank[i] = a[i + 1] - a[i] - 1, tot += blank[i];
        printf("%d\n", tot - min(blank[1], blank[n - 1]));
    }
    return 0;
}

L-hdu 6228 Tree(树dp)

题意:给出一棵有n个节点的树,现在你可以用k种颜色对节点染色,每种颜色对应一个集合,表示将树上所有这种颜色的点连起来经过的最少的边的三个月狂。现在需要求所有集合取交集后最大是几。
思路:题意很绕,然并卵,考虑每条边的贡献即可,若它左右两端点的数量大于k,显然贡献度为1。加和即可。

#include <bits/stdc++.h>
using namespace std;
int T, n, k, ans;
const int maxn = 200000 + 5;
vector<int>G[maxn];
int siz[maxn];
int dfs(int cur, int fa)
{
    siz[cur] = 1;
    for(auto o : G[cur])    if(o != fa)
    {
        int sonSize = dfs(o, cur);
        if(sonSize >= k && n - sonSize >= k)    ans++;
        siz[cur] += siz[o];
    }
    return siz[cur];
}
int main()
{
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; i++) G[i].clear();
        for(int i = 0; i < n - 1; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            G[x].push_back(y);
            G[y].push_back(x);
        }
        ans = 0;
        dfs(1, -1);
        printf("%d\n", ans);
    }
    return 0;
}

M-hdu 6229 Wandering Robots(找规律)

有一个机器人 一开始在(0,0)点上,每一步机器人有n种操作,停在原地,走向四周没有障碍物的方格。概率平均分布。 问你无限步后,机器人停留在矩阵右下部的概率是多少。
思路:有个规律,找到就好做了,自己下一步能去哪几个点,那么自己这个点的贡献度为几。具体好像和马尔科夫链有关?

#include <bits/stdc++.h>
using namespace std;

map<pair<int,int>, int>ma;
int dx[] = {0, 0, -1, 1, 0};
int dy[] = {1, -1, 0, 0, 0};
pair<int, int>nodes[1005];
int main()
{
    int n, k, T;
    scanf("%d", &T);
    for(int cas = 1; cas <= T; cas++)
    {
        scanf("%d%d", &n, &k);
        long long tot = 5LL * n * n - 4LL *  n;
        long long tot2 = 5LL * n * (n + 1) / 2 - 2LL * (n + 1);
        ma.clear();
        for(int i = 0; i < k; i++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            ma[{x, y}] = 1;
            nodes[i] = {x, y};
        }
        long long up = 0, down = 0;
        for(int i = 0; i < k; i++)
        {
            int x = nodes[i].first, y = nodes[i].second;
            int cnt = 0;
            for(int j = 0; j < 4; j++)
            {
                int fx = x + dx[j], fy = y + dy[j];
                if(0 <= fx && fx < n && 0 <= fy && fy < n)
                {
                    cnt++;
                    if(ma[{fx, fy}])  continue;
                    if(fx + fy >= n - 1)  down++;
                    else up++;
                }
            }
            if(x + y >= n - 1)  down += cnt + 1;
            else up += cnt + 1;
        }

        long long fenmu = tot - up - down;
        long long fenzi = tot2 - down;
        long long g = __gcd(fenmu, fenzi);
        fenmu /= g, fenzi /= g;
        printf("Case #%d: %lld/%lld\n", cas, fenzi, fenmu);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_29556211/article/details/78748336