【2012天津区域赛】部分题解 hdu4431—4441

1001:

题意:
给你13张麻将牌,问可以胡哪些张

思路:

枚举可能接到的牌,然后dfs判断能否胡

1002:

题意:

已知n,m 求 n的所有约数在m进制下的平方和

做法:
队长用java高精度写的

代码:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.PrintWriter;
import java.io.ObjectInputStream.GetField;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;

public class Main {

    static BigInteger getSum(int i, int base){
        BigInteger ans= BigInteger.ZERO;
        BigInteger divider = BigInteger.valueOf(i);
        String s = divider.toString(base);

        for (int j = 0; j < s.length(); j++) {
            BigInteger k = new BigInteger(s.substring(j, j + 1),
                    base);
            ans = k.multiply(k).add(ans);
        }
        return ans;
    }

    public static void main(String[] args) {
        Scanner cin = new Scanner(new BufferedInputStream(System.in));
        PrintWriter cout = new PrintWriter(new BufferedOutputStream(System.out));

        while (cin.hasNext()) {
            int n = cin.nextInt();
            int base = cin.nextInt();

            BigInteger ans = BigInteger.ZERO;
            for (int i = 1; i * i <= n; i++){
                if (n % i == 0) {
                    // i是divider
                    ans = ans.add(getSum(i, base));
                    if(i*i!=n)
                        ans = ans.add(getSum(n/i, base));
                }

            }
            cout.println(ans.toString(base).toUpperCase());
        }

        cin.close();
        cout.close();
    }

}

1003:

题意:
给定一串数,每次有三种操作:

1.把当前数加/减1

2.当前数和后面一个数加/减1

3.当前数和后面两个数加/减1

(加减完后的结果是在0~9循环的)

求把当前状态变到目标状态需要的最小操作数

做法:

处理到每个数的时候最多对后面两个数产生影响,因此十进制最多有 10^2=100 种情况,可以全部存下
可以进行dp,dp[i][j]表示前i个数已经达到目标状态 ,第i+1个数和第i+2个数的被操作情况为j(状压一下)的最小操作数,转移只需要枚举三种操作的次数即可

代码:

#include <iostream>
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
using namespace std;
#define inf 100000
int mod(int x)
{
    if(x>=0)
        return x%10;
    else
        return (10+x%10)%10;
}
char s[1010];
char to[1010];
int dp[1010][1010];
int num[3];
int tmp[3];
int p[3]= {1,20,400};
int main()
{
    while(scanf("%s%s",s+1,to+1)!=EOF)
    {
        memset(dp,0x3f,sizeof(dp));
        dp[0][210]=0;
        int n=strlen(s+1);
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<400; j++)
            {
                if(dp[i-1][j]>=inf)
                    continue;
                for(int k=0; k<2; k++)
                {
                    num[k]=(j%p[k+1])/p[k];
                }
                int cha=mod(to[i]-s[i]-(num[0]-10));
                for(int a=0; a<=cha; a++)
                {
                    for(int b=0; a+b<=cha; b++)
                    {
                        int c=cha-a-b;
                        tmp[0]=num[1]-10+b+c;
                        tmp[0]=tmp[0]%10+10;
                        tmp[1]=c+10;
                        dp[i][tmp[0]+tmp[1]*20]=min(dp[i][tmp[0]+tmp[1]*20],dp[i-1][j]+cha);
                    }
                }
                cha=10-cha;
                for(int a=0; a<=cha; a++)
                {
                    for(int b=0; a+b<=cha; b++)
                    {
                        int c=cha-a-b;
                        tmp[0]=10-(20-num[1]+b+c)%10;
                        tmp[1]=10-c;
                        dp[i][tmp[0]+tmp[1]*20]=min(dp[i][tmp[0]+tmp[1]*20],dp[i-1][j]+cha);
                    }
                }
            }
        }
        //printf("%d\n",dp[1][9+9*20]);
        //printf("%d\n",dp[2][9+10*20]);
        printf("%d\n",dp[n][210]);
    }
    return 0;
}

1005:

题意:

一个图有n个点,初始在点1,每次加满油后最多能跑d距离,现在点1有一个加油站,问环游全程回到1需要怎么建加油站

第i点建加油站的话 二进制第i位为1,答案要满足建造情况的二进制数最小

做法:

贪心,要尽量要高位的点不建,先假设所有点建了,再从大到小考虑,如果当前点不建也能满足需求,则把该点加油站删去

因为要考虑连通性所以判断是否满足需求要用bfs

代码:

#include <iostream>
#include <stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<ctype.h>
#include<queue>
#include<math.h>
using namespace std;
int g[150][150];
int x[150];
int y[150];
int vi[150];
int vis[150];
int n,d;
queue<int>q;
int check()
{
    memset(vis,0,sizeof(vis));
    while(!q.empty())
        q.pop();
    q.push(0);
    while(!q.empty())
    {
        int now=q.front();
        vis[now]=1;
        q.pop();
        for(int i=0;i<n;i++)
        {
            if(!vis[i])
            {
                if(g[now][i]<=d/2)
                {
                    vis[i]=1;
                }
                if(g[now][i]<=d&&vi[i])
                {
                    q.push(i);
                }
            }
        }
    }
    for(int i=0;i<n;i++)
    {
        if(vis[i]==0)
            return 0;
    }
    return 1;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(scanf("%d%d",&n,&d)!=EOF)
    {
        for(int i=0;i<n;i++)
        {
            vi[i]=1;
        }
        for(int i=0; i<n; i++)
        {
            scanf("%d%d",x+i,y+i);
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                g[i][j]=ceil(sqrt((double)((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))));
            }
        }
        if(check()==0)
        {
            puts("-1");
            continue;
        }
        for(int i=n-1; i>=1; i--)
        {
            vi[i]=0;
            if(!check())
                vi[i]=1;
        }
        int f=1;
        for(int i=n-1; i>=0; i--)
        {
            if(vi[i])
            {
                printf("1");
                f=0;
            }
            else
            {
                if(f==0)
                    printf("0");
            }
        }
        puts("");

    }
    return 0;
}

1006:

1008:

题意:

很简单的高中数学签到题

思路:

代码:

#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const double eps = 1e-8;
double x, y;
double p, q;
double fun1()
{
    double a1 = q*p*p*(x+y);
    double a2 = q*p*(1-p)*x;
    double a3 = q*p*(1-p)*y;
    double a4 = (1-q)*x;
    return a1+a2+a3+a4;
}
double fun2()
{
    double a1 = (1-q) * p*p*(x+y);
    double a2 = (1-q)*p*(1-p)*x;
    double a3 = (1-q)*p*(1-p)*y;
    double a4 = (q)*y;
    return a1+a2+a3+a4;;
}
int main()
{

    int t;
    cin>>t;
    while (t--)
    {
        scanf ("%lf%lf%lf%lf",&x, &y, &p, &q);
        if (fun1() > fun2())
        {
            printf("tiger %.4f\n", fun1());
        }
        else
            printf("wolf %.4f\n", fun2());
    }
    return 0;
}

1011:

时间: 2024-08-03 21:33:27

【2012天津区域赛】部分题解 hdu4431—4441的相关文章

【2012长春区域赛】部分题解 hdu4420—4430

这场比赛特点在于两个简单题太坑,严重影响了心情..导致最后只做出两题....当然也反映出心理素质的重要性 1002: 题意:一个矩阵b[n][n]通过数组 a[n]由以下规则构成,现在已知b[n][n]问是否有对应的数组a[n] 解法: 首先都是位运算所以不同位是不会互相影响的,即可按位考虑. 又发现,只要知道a[0]就可以算出通过b[0][]算出所有的a[],这样可以假设a[0]为0或1,由b[0][]得到一个完整的数组a[],再check这个数组a是否能正确的得到其他的b[][]即可 时间复

HDU4436---str2int 后缀树组(12年天津区域赛)

str2int Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1568    Accepted Submission(s): 540 Problem Description In this problem, you are given several strings that contain only digits from '0'

【组队训练】2013天津区域赛

三题,按现场排名应该是80名,铜牌靠后. 几次训练发现自己的心理素质实在是太!差!了!一开始,老规矩,我k题,zrA题,ysB题. A题大模拟,比较费时,zr先看了过了几个人的H,31mins,1A B题过的人越来越多,我看了N久终于看懂K题……不会做……我去问ys怎么样,他说了下题意,我觉得很水的暴力,让他直接写,他一直在和我讲说复杂度不够.我有点不耐烦,直接上机写.写的过程中出了点小问题,不过还是水题,一个小时左右1A #include <cstdio> #include <cstr

hdu 4463 有一条边必须加上 (2012杭州区域赛K题)

耐克店 和 苹果店必须相连 Sample Input42 30 01 00 -1 1 -10 Sample Output3.41 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <algorithm> 5 # include <cmath> 6 # define LL long long 7 using namespace std ; 8

HDU 4438 Hunters 区域赛水题

本文转载于 http://blog.csdn.net/major_zhang/article/details/52197538 2012天津区域赛最水之题: 题意容易读懂,然后就是分情况求出A得分的数学期望,所谓数学期望就是在该概率下的平均得分. 现在就是两种方案,Alice要根据输入给出的数据情况选出最优方案,也就是先选老虎,还是狼. 1.A先选老虎: a.B也先选老虎,则得分为Q(P*X+P*Y); //打完老虎还要打狼 b.B选狼,则两人可以直接获得猎物,则得分为(1-Q)*X 所以1方案

2014年北京赛区区域赛现场赛A,D,H,I,K题解(hdu5112,5115,5119,5220,5122)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 下午在HDU上打了一下今年北京区域赛的重现,过了5题,看来单挑只能拿拿铜牌,呜呜. 先将这五题的题解放上来,剩余题目等搞出来再补上 A题 A Curious Matt Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Problem Description T

UVALive 7146 (贪心+少许数据结构基础)2014acm/icpc区域赛上海站

这是2014年上海区域赛的一道水题.请原谅我现在才发出来,因为我是在太懒了.当然,主要原因是我刚刚做出来. 其实去年我就已经看到这道题了,因为我参加的就是那一场.但是当时我们爆零,伤心的我就再也没有看过那一场的题了.昨天我的队友的高中同学建议我们一起来打一打这场比赛吧,然后我才再次回顾这场比赛.结果一堆琐事,我一共也没有做多久的题,我的队友扎扎实实看了5个小时的题,把另一道水题给过了.全场我们也只过了那么一道题.学姐说,做重现赛和现场赛比较,需要去掉一题,那么我们又爆零了. 题意: 我方有n个人

鞍山区域赛的总结+反思

玩acm大概也有半年了吧,大概是从大一下学期中后段的那一段时间开始接触acm的,暑假参加了集训之后,就开始了区域赛的网络赛的选拔,哎弱校没人权,最终组好的队伍也就那么四五队,弱校的acm氛围简直太差了,无法吸引很多的学生一起来玩耍,网络赛选拔的时候我们队是零贡献的,因为,有些师兄队要和我们共用一个账号,那些水题往往被他们很快先ac掉了,难题我们又做不了,只能让师兄们去做,多亏了他们,让scnu的每个区域赛都获得了现场赛的名额.哎 牡丹江凑不齐人数,结果最终只能放弃这个赛区了.两个字,弱校----

16年区域赛训练计划

训练时间: 星期二的晚上7:00 ~ 10:00 的小训练星期四的中午12:00 ~ 17:00的模拟区域赛训练(大仙视公司情况参加)星期六的中午12:00 ~ 17:00的模拟区域赛训练 平时不训练的时候:1.补题:补训练赛中的可做题,尽量脱题解补,特别对于自己算法负责的部分需要好好总结.2.参加比赛,学弟比较需要参加,因为比较缺乏这方面的经验.有选择的参加以下高质量的比赛:codeforces[特点:什么算法都有,难度区分明显,rating制度很科学]Topcoder(需要VPN,学弟可以用