2017 ACM/ICPC Asia Regional Qingdao Online

题目链接


01:http://acm.hdu.edu.cn/showproblem.php?pid=6206
02:http://acm.hdu.edu.cn/showproblem.php?pid=6207
03:http://acm.hdu.edu.cn/showproblem.php?pid=6208
04:http://acm.hdu.edu.cn/showproblem.php?pid=6209
05:http://acm.hdu.edu.cn/showproblem.php?pid=6210
06:http://acm.hdu.edu.cn/showproblem.php?pid=6211
07:http://acm.hdu.edu.cn/showproblem.php?pid=6212
08:http://acm.hdu.edu.cn/showproblem.php?pid=6213
09:http://acm.hdu.edu.cn/showproblem.php?pid=6214
10:http://acm.hdu.edu.cn/showproblem.php?pid=6215
11:http://acm.hdu.edu.cn/showproblem.php?pid=6216
 这场比赛交流不想之前那么充足可能是疲劳比赛吧,做出5题后面做10失败很可惜。

一些题解


01 Apple

 这道题就是给定三个点,要你看第四个点是否在三个点组成圆内。
 这道题就是基本求圆的数学题就是卡精度,然后大家纷纷使用java,,,,

import java.io.BufferedInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
import java.util.Vector;

public class Main
{
    private static Scanner cin;
    public static void main(String[] args) throws IOException
    {

        cin = new Scanner(new BufferedInputStream(System.in));
        int T = cin.nextInt();
        for (int cnt = 1; cnt <= T; cnt++)
        {
            BigDecimal
                    two = new BigDecimal("2.0000"),
                    x1=cin.nextBigDecimal(), y1=cin.nextBigDecimal(),
                    x2=cin.nextBigDecimal(),y2=cin.nextBigDecimal(),
                    x3=cin.nextBigDecimal(),y3=cin.nextBigDecimal(),
                    x=cin.nextBigDecimal(), y=cin.nextBigDecimal(),x0,y0;

            BigDecimal tmp1,tmp2,tmp3;

            tmp1 = (x1.multiply(x1).subtract(x2.multiply(x2)).add(y1.multiply(y1)).subtract(y2.multiply(y2))).multiply(y1.subtract(y3));
            tmp2 = ((x1.multiply(x1).subtract(x3.multiply(x3)).add(y1.multiply(y1)).subtract(y3.multiply(y3))).multiply(y1.subtract(y2)));
            x0 = tmp1.subtract(tmp2);

            tmp3 = (y1.subtract(y3)).multiply(x1.subtract(x2)).multiply(two). subtract((y1.subtract(y2)).multiply(x1.subtract(x3)).multiply(two));



            x0=x0.divide(tmp3,10, BigDecimal.ROUND_HALF_EVEN);

            tmp1 = (x1.multiply(x1).subtract(x2.multiply(x2)).add(y1.multiply(y1)).subtract(y2.multiply(y2))).multiply(x1.subtract(x3));
            tmp2 = ((x1.multiply(x1).subtract(x3.multiply(x3)).add(y1.multiply(y1)).subtract(y3.multiply(y3))).multiply(x1.subtract(x2)));
            y0 = tmp1.subtract(tmp2);

            tmp3 = (y1.subtract(y2)).multiply(x1.subtract(x3)).multiply(two). subtract((y1.subtract(y3)).multiply(x1.subtract(x2)).multiply(two));
            y0=y0.divide(tmp3,10, BigDecimal.ROUND_HALF_EVEN);

            BigDecimal dis1,dis2;

            dis1=(x0.subtract(x1)).multiply(x0.subtract(x1)).add(y0.subtract(y1).multiply(y0.subtract(y1)));

            dis2=((x0.subtract(x)).multiply(x0.subtract(x)).add(y0.subtract(y).multiply(y0.subtract(y))));

            //System.out.println(dis1);System.out.println(dis2);

            if(dis1.compareTo(dis2)<0)
                System.out.println("Accepted");
            else
                System.out.println("Rejected");

        }
    }
}

03 The Dominator of Strings

 这道题的意思就是给你一堆字符串让你求其中是否有一个串使其他所有串都是他的子串。
 那么父串一定是最长的那一个其他所有串都是其子串才有可能,如果一样长就判断相等就行,那么.find()一下就好了。

#include <bits/stdc++.h>

using namespace std;
string ss[100005];
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int n;
        scanf("%d", &n);
        getchar();
        int bj = 1;
        int maxx = 0;
        string::size_type idx;
        for(int i = 1;i <= n;i++)
        {
            char ls;
            ss[i] = "";
            while(ls = getchar(), ls != '\n')
            {
                ss[i] += ls;
            }
            int len = ss[i].size();
            if(len > maxx)
            {
                bj = i;
                maxx = len;
            }
        }
        int flag = 1;
        for(int i = 1;i <= n;i++)
        {
            if(bj == i)
                continue;
            else if(ss[i].size() == maxx)
            {
                if(ss[i] != ss[bj])
                {
                    flag = 0;
                    break;
                }
            }
            else if(ss[i].size() < maxx)
            {
                idx = ss[bj].find(ss[i]);
                if(idx == string::npos)
                {
                    flag = 0;
                    break;
                }
            }
        }
        if(flag == 0)
            printf("No\n");
        else
            cout<<ss[bj]<<endl;
    }
    return 0;
}

08 Chinese Zodiac

 题目给定两个人的生肖,并且一个人要比另一个人年轻,问他们差几岁,那么直接用map预处理一下各个生肖的岁数,如果男的生肖比女的小直接相减即可,如果一样就差12岁,如果男的比女的大了,说明女的大了一轮,直接12减去生肖差即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000010;
const int inf=0x3f3f3f3f;
map<string,int> mp;
int main()
{
    int t;
    scanf("%d",&t);
    mp["rat"]=1,mp["ox"]=2,mp["tiger"]=3,mp["rabbit"]=4,mp["dragon"]=5,mp["snake"]=6,mp["horse"]=7,mp["sheep"]=8,mp["monkey"]=9,mp["rooster"]=10,mp["dog"]=11,mp["pig"]=12;
    while(t--)
    {

        string a,b;
        int x,y;
        cin>>a>>b;
        x=mp[a],y=mp[b];

        int ans=0;
        if(x==y) ans=12;
        else if(x<y) ans=abs(x-y);
        else if(x>y) ans=12-abs(x-y);

        printf("%d\n",ans);

    }

    return 0;
}

09 Smallest Minimum Cut

 最小割的最小边模板题。

#include <bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int MAXN = 1010;
const int INF = 1<<30;
struct Edge
{
    int to, cap;
};
int n,m,s,t, np,nc;
vector<Edge> edge;
vector<int>  G[MAXN];
int d[MAXN], cur[MAXN];
void init()
{
        memset(d,0,sizeof(d));
        memset(cur,0,sizeof(cur));
        memset(G,0,sizeof(G));
}
void AddEdge(int from, int to, int cap)
{
    edge.push_back((Edge){to, cap});
    edge.push_back((Edge){from, 0});
    int id = edge.size();
    G[from].push_back(id-2);
    G[to].push_back(id-1);
}
bool bfs()
{
    memset(d, 0, sizeof(d));
    queue<int> Q;
    Q.push(s);
    d[s] = 1;
    while(!Q.empty())
    {
        int x = Q.front(); Q.pop();
        if(x == t) return true;
        for(int i=0; i<G[x].size(); i++)
        {
            Edge& e = edge[G[x][i]];
            if(!d[e.to] && e.cap>0)
            {
                d[e.to] = d[x]+1;
                Q.push(e.to);
            }
        }
    }
    return false;
}
int dfs(int x, int a)
{
    if(x == t || a == 0) return a;
    int flow = 0, f;
    for(int& i=cur[x]; i<G[x].size(); i++)
    {
        Edge& e = edge[G[x][i]];
        if(d[x]+1 == d[e.to] && (f=dfs(e.to, min(a, e.cap)))>0)
        {
            e.cap -= f;
            edge[G[x][i]^1].cap += f;
            flow += f;
            a -= f;
            if(a == 0) break;
        }
    }
    return flow;
}
int Maxflow()
{
    int flow = 0;
    while(bfs())
    {
        memset(cur, 0, sizeof(cur));
        flow += dfs(s, INF);
    }
    return flow;
}
int main()
{
    int qs;
    scanf("%d",&qs);
    while(qs--)
    {
        init();
        scanf("%d%d",&n,&m);
        scanf("%d%d",&s,&t);
        int x,y,z;
       for(int i=1;i<=m;i++)
       {
           scanf("%d%d%d",&x,&y,&z);
           AddEdge(x,y,z*(m+1)+1);
       }
       printf("%d\n",Maxflow()%(m+1));
    }
}

11 A Cubic number and A Cubic Number

 题目是说给定一个素数问它是不是由两个数的三次方的差,那么其实一定是相邻两个的差才会出现素数因为(a + n)^3 - a^3 = 3 * n^2 * a + 3 * a^2 * n + n ^3一定有个因素n而只有n = 1才有可能。
 那知道上面这个公式,再去求就简单了。

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
map<LL,int>M;
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int flag = 0;
        LL p;
        scanf("%I64d", &p);
        LL ans = (p - 1);
        if(ans % 3 != 0)
            flag = 0;
        else
        {
            ans /= 3;
            LL s = sqrt(ans);
            if(s *(s + 1) == ans)
                flag = 1;
        }
        if(flag == 1)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

补题


10 Brute Force Sorting

 题目是说,给定一串数字要你每次删去所有递减的子串,问你最后剩下的数字串是什么。
 暴力是直接gg的那么看了网上题解说是要用双向链表扫,每次直接删去节点然后保存删之前的节点。

#include <bits\stdc++.h>

using namespace std;
const int maxn = 100004;
int a[maxn], leff[maxn], rigg[maxn];
int que[maxn], top;
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        memset(a, 0, sizeof(a));
        int n;
        scanf("%d", &n);
        top = 0;
        int ans = n;
        rigg[0] = 1;
        leff[n + 1] = n;
        for(int i = 1;i <= n;i++)
        {
            scanf("%d", &a[i]);
            rigg[i] = i + 1;
            leff[i] = i - 1;
            que[top++] = i;
        }
        int flag = 1;
        while(flag)
        {
            flag = 0;
            int now = 0;
            int s = 0;
            while(now < top)
            {
                int i = que[now], ss = 0;
                while(rigg[i] <= n)
                {
                    if(a[i] > a[rigg[i]])ss++, i = rigg[i], flag = 1;
                    else
                        break;
                }
                if(ss)ans -= (ss + 1);
                if(ss)
                {
                    rigg[leff[que[now]]] = rigg[i];
                    leff[rigg[i]] = leff[que[now]];
                    que[s++] = leff[que[now]];
                }
                while(que[now] <= i&&now < top)now++;
            }
            top = s;
        }
        printf("%d\n", ans);
        int now = 0;
        while(now <= n)
        {
            if(now != 0)
                printf("%d ", a[now]);
            now = rigg[now];
        }
        printf("\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值