ACM Summer Training Warm up

ACM Summer Training Warm up

ACM Summer Training Warm up_第1张图片
Cover

热身水题

题目

HDU 4500 小Q系列故事——屌丝的逆袭

思路

简单的模拟,一个数组读入数据,一个数组计算维护结果

#include
#include
#include
using namespace std;
int n,m,x,y,Max,map[22][22],s[22][22];
int main()
{
    while(scanf("%d %d",&n,&m))
    {
        if(n == 0 && m == 0)
            break;
        memset(map,0,sizeof(map));
        memset(s,0,sizeof(s));
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                scanf("%d",&map[i][j]);
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
            {
                if(map[i][j] * map[i-1][j] < 0)
                    s[i][j] += abs(map[i-1][j]);
                else
                    s[i][j] -= abs(map[i-1][j]);
                
                if(map[i][j] * map[i+1][j] < 0)
                    s[i][j] += abs(map[i+1][j]);
                else
                    s[i][j] -= abs(map[i+1][j]);
                
                if(map[i][j] * map[i][j-1] < 0)
                    s[i][j] += abs(map[i][j-1]);
                else
                    s[i][j] -= abs(map[i][j-1]);

                if(map[i][j] * map[i][j+1] < 0)
                    s[i][j] += abs(map[i][j+1]);
                else
                    s[i][j] -= abs(map[i][j+1]);
            }

            Max = -9999;

            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= m; j++)
                    if(s[i][j] > Max)
                    {
                        x = i;
                        y = j;
                        Max = s[i][j];
                    }
            printf("%d %d %d\n",x,y,Max);
    }
    return 0;
}

HDU 2109 Fighting for HDU

思路

简单排序,sort()

#include
#include
using namespace std;
int n,a[110],b[110];
int main()
{
    while(scanf("%d",&n) && n)
    {
        a[0] = 0; b[0] = 0;
        for(int i = 1; i <= n; i++)
            scanf("%d",&a[i]);
        for(int i = 1; i <= n; i++)
            scanf("%d",&b[i]);
        sort(a+1,a+1+n);
        sort(b+1,b+1+n);
        for(int i = 1; i <= n; i++)
            if(a[i] > b[i])
                a[0] += 2;
            else
                if(a[i] < b[i])
                    b[0] += 2;
            else
                a[0] += 1,b[0] += 1;
        printf("%d vs %d\n",a[0],b[0]);
    }
    return 0;
}

HDU 2111 Saving HDU

思路

贪心+排序,优先对单价进行排序

#include
#include
using namespace std;
struct goods
{
    double v;
    double p;
    double r;
}g[110];
int v,n,sum;
bool cmp(goods x,goods y)
{
    return x.p > y.p;
}
int main()
{
    while(scanf("%d%d",&v,&n) && v)
    {
        sum = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%lf%lf",&g[i].p,&g[i].v);
            g[i].r = g[i].p / g[i].v;
        }
        sort(g,g+n,cmp);
        for(int i = 0; i < n; i++)
            if(v >= g[i].v)
                v -= g[i].v, sum += g[i].p * g[i].v;
            else
            {
                sum += v * g[i].p;
                break;
            }
        printf("%d\n",sum);
    }
    return 0;
}

HDU 3787 A+B

思路

字符串转整形再进行求和即可

#include
#include
using namespace std;
int x,y,l;
char s1[20],s2[20];
bool f;
int main()
{
    while(scanf("%s%s",s1,s2)!=EOF)
    {
        getchar();
        l = strlen(s1);
        x = 0; y = 0;
        for(int i = 0; i < l; i++)
            if(s1[i] >= '0' && s1[i] <= '9')
                x = x * 10 + (s1[i] - '0');
        l = strlen(s2);
        for(int i = 0; i < l; i++)
            if(s2[i] >= '0' && s2[i] <= '9')
                y = y * 10 + (s2[i] - '0');
        if(s1[0] == '-')
            x = -x;
        if(s2[0] == '-')
            y = -y;
        printf("%d\n",x+y);
    }
    return 0;
}

HDU 2108 Shape of HDU

思路

遍历所有的点,任意连续三点构成两个向量,根据向量相乘的结果,大于等于0为凸多边形(锐角和直角),小于0为凹多边形(钝角)

#include
using namespace std;
struct angle
{
    int x;
    int y;
}a[1010];
int n;
bool f,r;
bool judge(angle a,angle b,angle c)
{
    return ((c.y - a.y) * (b.x-a.x) - (c.x - a.x) * (b.y - a.y) ) < 0 ;
}
int main()
{
    while(scanf("%d",&n) && n)
    {
        f = true; r = true;
        for(int i = 0; i < n; i++)
            scanf("%d%d",&a[i].x,&a[i].y);
        for(int i = 0; i < n; i++)
        {
            if(i == 0)
                r = judge(a[0],a[1],a[n - 1]);
            else
                if(i == n - 1)
                    r = judge(a[n - 1],a[0],a[n - 2]);
            else
                r = judge(a[i],a[i + 1],a[i - 1]);
            if(r)
            {    
                f = false; 
                printf("concave\n");
                break;
            }
        }
        if(f)
            printf("convex\n");
    }
    return 0;
}

HDU 3783 ZOJ

思路

读入字符串,把zoj三个字母分别存起来,输出时候按照zoj数目依次顺序输出

#include
#include
using namespace std;
char s[110],s1[4] = {"ZOJ"};
int a[4];
int main()
{
    while(scanf("%s",s)!=EOF)
    {
        if(s[0] == 'E')
            break;
        memset(a,0,sizeof(a));
        for(int i = 0; i < strlen(s); i++)
            if(s[i] == 'Z')
                a[0]++;
            else
                if(s[i] == 'O')
                    a[1]++;
            else
                a[2]++;
        for(int i = 0; i < 3; i++)
            while(a[i])
            {
                a[i]--;
                printf("%c",s1[i]);
                for(int j = i+1; j < 3; j++)
                    if(a[j])
                        a[j]--,printf("%c",s1[j]);
            }
        printf("\n");
    }
    return 0;
}

HDU 3784 继续xxx定律

思路

3n+1定理,多加一个数组判断当前结果是否出现过,最后输出

#include
#include
#define M 300010
using namespace std;
int n,t,a[M];
bool m[M],f;
int main()
{
    while(scanf("%d",&n)!=EOF && n)
    {
        memset(a,0,sizeof(a));
        memset(m,1,sizeof(m));
        f = true;
        for(int i = 0; i < n; i++)
            scanf("%d",&a[i]);
        for(int i = 0; i < n; i++)
            if(!m[a[i]])
                continue;
            else
            {
                t = a[i];
                while(t > 1)
                {
                    t = t % 2 == 0 ? t/=2 : (t * 3 + 1)/2;
                    m[t] = false;
                }
            }
        for(int i = n-1; i>= 0; i--)
            if(m[a[i]] && f)
            {
                f = false;
                printf("%d",a[i]);
            }
            else
                if(m[a[i]])
                    printf(" %d",a[i]);
        printf("\n");
    }
    return 0;
}

HDU 3788 ZOJ问题

思路

找规律,z前面o的个数乘以z和j之间的o的个数等于j后面o的个数

#include
#include
using namespace std;
char s[1010];
int a[3],p1,p2,x,y,z;
int main()
{
    while(scanf("%s",s)!=EOF)
    {
        memset(a,0,sizeof(a));
        x = 0; y = 0; z = 0;
        for(int i = 0,j = 0; i < strlen(s); i++)
            if(s[i] == 'z')
                p1 = i,x++;
            else
                if(s[i] == 'j')
                {
                    p2 = i,y++;
                }
            else
                z++;
        if(!x || !y || !z)
        {
            printf("Wrong Answer\n");
            continue;
        }
        else
            {
                for(int i = 0; i < p1; i++)
                    a[0]++;
                for(int i = p1 + 1; i < p2; i++)
                    a[1]++;
                for(int i = p2 + 1; i < strlen(s); i++)
                    a[2]++;
            }
        if(a[0] * a[1] == a[2])
            printf("Accepted\n");
        else
            printf("Wrong Answer\n");
    }
    return 0;
}

POJ 1002 487-3279

题目描述

给你一组数字或者字符串形式的电话号码,根据题目字母转换表要求进行转换成数字,统计每个电话号码出现次数,最后根据字典序和规定格式输出。

思路

简单的字符串转换数字,然后对数字进行排序,从小到大统计输出

#include
#include
#include
using namespace std;
char str[2010];
int n,i,j,l,sum,a[100010],map[26] = {2,2,2,3,3,3,4,4,4,5,5,5,6,6,6,7,0,7,7,8,8,8,9,9,9};
bool f;
int main()
{
        scanf("%d",&n);
        getchar();
        j = 0; f = true;
        memset(a,0,sizeof(a));
        while(n--)
        {
            scanf("%s",str);
            l = strlen(str);
            for(i = 0; i < l; i++)
                if(str[i] == '-')
                    continue;
                else
                    if(str[i] >= 'A' && str[i] <= 'Z')
                        a[j] = a[j] * 10 + map[(str[i] - 'A')];
                else
                    a[j] = a[j] * 10 + (str[i] - '0');
            j++;
        }
        sort(a,a+j);
        for(i = 0,sum = 1; i < j; i++)
            if(a[i] == a[i+1])
                sum++;
            else
                if(sum > 1)
                {
                    printf("%03d-%04d %d\n",a[i]/10000,a[i]%10000,sum);
                    f = false;
                    sum = 1;
                }
            else
                sum = 1;
        if(f)
            printf("No duplicates.\n");
    return 0;
}

HDU 1001 Sum Problem

题目描述

计算n!

思路

可以用高精度乘法模拟实现,或者暴力方法,根据等差数列求和公式,先除以2再乘以n+1,防止溢出

#include
using namespace std;
double n;
int main()
{
    while(scanf("%lf",&n)!=EOF)
    {
        printf("%0.lf\n\n",n/2*(1+n));
    }
    return 0;
}

HDU 1016 Prime Ring Problem

题目描述

给你1~n构成一个素数环,相邻两个的和是素数

思路

先打表记录素数,然后深度搜索,以当前选择了几个数为状态,当前选择个数是否大于n作为边界条件,最后用数组保存维护结果

#include
#include
#include
using namespace std;
const int M = 10010;
int c,n,a[M];
bool vis[M],prime[M];
void dfs(int num)
{
    if(num > n && !prime[a[1] + a[num-1]])
    {
        printf("%d",a[1]);
        for (int j = 2; j <= n; j++)
            printf(" %d",a[j]);
        printf("\n");
        return ;
    }
    for (int i = 2; i <= n; i++)
    {
        if(!vis[i] && !prime[i + a[num-1]])
        {
            vis[i] = 1;
            a[num++] = i;
            dfs(num);
            vis[i] = 0;
            num--;
        }
    }
    return ;
}
int main()
{
    memset(prime,0,sizeof(prime));
    prime[1] = 1;
    for (int i = 2; i <= 100; i++)
        if(!prime[i])
            for (int j = i + i; j <= 100; j+=i)
                prime[j] = 1;
    while(cin>>n)
    {
        memset(vis,0,sizeof(vis));
        a[1] = 1;
        vis[1] = 1;
        printf("Case %d:\n",++c);
        dfs(2);
        printf("\n");
    }
    return 0;
}

HDU 2612 Find a way

题目描述

Y和M要去麦当劳@约会,问两个人到达同一个麦当劳的距离和最短是多少

思路

分别对Y和M进行广度搜索,最后遍历图上的麦当劳位置输出最短距离

#include
#include
#include
#include
using namespace std;
const int M = 210;
const int inf = 0xffffff;
struct node
{
    int x,y,step;
};
int n,m,f,ans,step[M][M][2],dir[4][2]={1,0,0,1,-1,0,0,-1};
char map[M][M];
bool vis[M][M];
void bfs(int x,int y)
{
    node curr,next;
    curr.x = x;
    curr.y = y;
    curr.step = 0;
    queue Q;
    Q.push(curr);
    while(!Q.empty())
    {
        curr = Q.front();
        Q.pop();
        next.step = curr.step + 1;
        for (int i = 0; i < 4; i++)
        {
            next.x = curr.x + dir[i][0];
            next.y = curr.y + dir[i][1];
            if(next.x >= 0 && next.x < n && next.y >= 0 && next.y < m && !vis[next.x][next.y] && map[next.x][next.y] != '#')
            {
                vis[next.x][next.y] = 1;
                step[next.x][next.y][f] = next.step;
                Q.push(next);
            }
        }
    }
    return ;
}
int main()
{
    while(cin>>n>>m)
    {
        getchar();
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                step[i][j][0] = step[i][j][1] = inf;
        for (int i = 0; i < n; i++)
            scanf("%s",map[i]);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                if(map[i][j] == 'Y')
                {
                    memset(vis,0,sizeof(vis));
                    f = 0;
                    vis[i][j] = 1;
                    bfs(i,j);
                }
                else
                    if(map[i][j] == 'M')
                    {
                        memset(vis,0,sizeof(vis));
                        f = 1;
                        vis[i][j] = 1;
                        bfs(i,j);
                    }
        ans = inf;
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                if(map[i][j] == '@')
                    ans = min(ans,step[i][j][0] + step[i][j][1]);
        printf("%d\n",ans*11);
    }
    return 0;
}

你可能感兴趣的:(ACM Summer Training Warm up)