CUGBACM Codeforces Tranning 1 解题报告

原文链接:比赛链接

  • Problem A Before an Exam (水题)
  • Problem B The least round way (DP)
  • Problem C Tic-tac-toe (模拟)
  • Problem D Ancient Berland Circus (几何)
  • Problem E Least Cost Bracket Sequence (贪心)

做的时候还是比较心急啊,,,

A题,第一题你懂得。本题主要处理的地方是最后时间的得出,开始我认为只要最后算上每天的最长时间然后满足总时间以后加每天的最短时间,中间只需要处理一天,结果给跪了。

AC代码:

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<iomanip>
#include<string>
#include<cmath>
#include<vector>
#include <queue>
#include <cstdlib>
#include<algorithm>
using namespace std;
int main()
{
    int i,d,sum,s=0,w=0;
    int m[31],n[31],t[31];
    cin>>d>>sum;
    for(i=1; i<=d; i++)
    {
        cin>>m[i]>>n[i];
        s+=n[i];
        w+=m[i];
    }
    if(w>sum||s<sum)
        cout<<"NO";
    if(w<=sum&&s>=sum)
    {
        cout<<"YES"<<endl;
        if(w==sum)
            for(i=1; i<=d; i++)
                cout<<m[i]<<" ";
        else
        {
            for(i=1; i<=d; i++)
            {
                t[i]=n[i]-m[i];
            }
            int  p=1;
            int e=m[1];
            while (w+t[p]<=sum)
            {
                m[p]=n[p];
                w+=t[p];
                p++;
            }
            m[p]=m[p]+sum-w;
            for(i=1; i<=d; i++)
            {
                cout<<m[i];
                if(i!=d)
                    cout<<" ";
            }
        }
    }
    return 0;
}

B题:dp

题意:题意是给你一个n * n 的矩阵,他的每一步只能向下或向右走,问从左上角到右下角的路径中乘积中零最少的路径,输出路径和零的个数。

开始误以为是DFS,未果,后来看题解才想起DP,dp找到含2和5最少的路径,取其中的最小值,写的时候注意第一个数为0的情况

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<iomanip>
#include<string>
#include<cmath>
#include<vector>
#include <queue>
#include <cstdlib>
#include<algorithm>
using namespace std;
int mat[1005][1005];
char direct[1005][1005][2];
int dp[1005][1005][2];
char path[2010];
int path_len;
int factors(int num, int base)
{
    int ret = 0;
    int fct = base;
    if (num == 0) return 1;
    while (num % fct == 0)
    {
        ret++;
        fct *= base;
    }
    return ret;
}
int mi(int a, int b)
{
    return a < b ? a : b;
}
int main()
{
    int n;
    scanf("%d", &n);
    bool zero = false;
    int zero_i;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            scanf("%d", &mat[i][j]);
            if (mat[i][j] == 0)
            {
                zero = true;
                zero_i = i;
            }
            dp[i][j][0]= factors(mat[i][j], 2);
            dp[i][j][1] = factors(mat[i][j], 5);
        }
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int k = 0; k < 2; k++)
            {
                if (i == 0 && j == 0) continue;
                if (i == 0)
                {
                    dp[i][j][k] += dp[i][j-1][k];
                    direct[i][j][k] = 'R';
                }
                else if (j == 0)
                {
                    dp[i][j][k] += dp[i-1][j][k];
                    direct[i][j][k] = 'D';
                }
                else
                {
                    dp[i][j][k] += dp[i-1][j][k] < dp[i][j-1][k] ? dp[i-1][j][k] : dp[i][j-1][k];
                    direct[i][j][k] = dp[i-1][j][k] < dp[i][j-1][k] ? 'D' : 'R';
                }
            }
        }
    }
    if (mi(dp[n-1][n-1][0], dp[n-1][n-1][1]) > 1 && zero)
    {
        printf("1\n");
        for (int i = 0; i < zero_i; i++) printf("D");
        for (int i = 0; i < n-1; i++) printf("R");
        for (int i = zero_i; i < n-1; i++) printf("D");
    }
    else
    {
        printf("%d\n", mi(dp[n-1][n-1][0], dp[n-1][n-1][1]));
        path_len = 0;
        int k = 1;
        if (dp[n-1][n-1][0] < dp[n-1][n-1][1]) k = 0;
        for (int i = n-1, j = n-1; i!=0||j!=0; )
        {
            path[path_len++] = direct[i][j][k];
            if (direct[i][j][k] == 'D')
            {
                i--;
            }
            else if (direct[i][j][k] == 'R')
            {
                j--;
            }
        }
        for (int i = 2 * (n - 1) - 1; i >= 0; i--) printf("%c", path[i]);
    }
    printf("\n");
    return 0;
}

C题:模拟

这道题WA的主要原因还是考虑不全面。平局只在棋盘放满的时候,不要多虑了。

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<iomanip>
#include<string>
#include<cmath>
#include<vector>
#include <queue>
#include <cstdlib>
#include<algorithm>
using namespace std;
int xcnt;
int ocnt;
char brd[3][3];
bool win(char sym)
{
    for (int i = 0; i < 3; i++)
    {
        if (brd[i][0] == sym && brd[i][1] == sym && brd[i][2] == sym) return true;
        if (brd[0][i] == sym && brd[1][i] == sym && brd[2][i] == sym) return true;
    }
    if (brd[1][1] != sym) return false;
    if (brd[0][0] == sym && brd[2][2] == sym) return true;
    if (brd[0][2] == sym && brd[2][0] == sym) return true;
    return false;
}
bool legal(void)
{
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            xcnt += brd[i][j] == 'X';
            ocnt += brd[i][j] == '0';
        }
    }
    if (xcnt - ocnt > 1) return false;
    if (xcnt - ocnt < 0) return false;
    if (win('X') && xcnt == ocnt) return false;
    if (win('0') && xcnt - ocnt == 1) return false;
    return true;
}
int main()
{
    xcnt = 0;
    ocnt = 0;
    char stmp[4];
    for (int i = 0; i < 3; i++)
    {
        scanf("%s", stmp);
        for (int j = 0; j < 3; j++) brd[i][j] = stmp[j];
    }
    do
    {
        if (!legal())
        {
            printf("illegal\n");
            break;
        }
        if (win('X'))
        {
            printf("the first player won\n");
            break;
        }
        if (win('0'))
        {
            printf("the second player won\n");
            break;
        }
        if (xcnt + ocnt == 9)
        {
            printf("draw\n");
            break;
        }
        if (xcnt == ocnt)
        {
            printf("first\n");
            break;
        }
        if (xcnt - ocnt == 1)
        {
            printf("second\n");
            break;
        }
    }
    while (true);
    return 0;
}

D题:几何问题

本题应用了海伦公式及圆心角计算等知识,几何什么的最喜欢了。

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<iomanip>
#include<string>
#include<cmath>
#include<vector>
#include <queue>
#include <cstdlib>
#include<algorithm>
#define pi acos(-1.0)
#define feq(a, b) (fabs((a)-(b))<1E-2)
using namespace std;
double fgcd(double a, double b){
     if (feq(a, 0))
         return b;
     if (feq(b, 0))
         return a;
     return fgcd(b, fmod(a, b));
}
double diameter(double a, double b, double c) {
   	double p = (a + b + c) / 2;
   	double s = sqrt(p * (p - a) * (p - b) * (p - c));
   	return a * b * c / (4 *s);
}
int main() {
	double x[3], y[3], d[3];
	int i =  0;
	while(~scanf("%lf%lf", &x[i], &y[i])) {
		i++;
		if(i == 3) {
			for(int j = 0; j < 3; ++j)
				d[j] = sqrt((x[j] - x[(j+1)%3]) * (x[j] - x[(j+1)%3]) + (y[j] - y[(j+1)%3]) * (y[j] - y[(j+1)%3]));
			double R = diameter(d[0], d[1], d[2]);
			double angle[4];
			for(int j = 0; j < 2; ++j)
			 	angle[j] = acos(1 - d[j] * d[j] / (2 * R * R));
	 		angle[2] = 2 * pi - angle[0] - angle[1];
 			angle[3] = fgcd(angle[0], fgcd(angle[1], angle[2]));
			printf("%.6lf\n", R * R * sin(angle[3]) / 2 * (2 * pi / angle[3]));
			i = 0;
		}
	}
}

E题:贪心

赛后看别人的题解才AC,

#include<iostream>
#include<stdio.h>
#include<cstring>
#include<iomanip>
#include<string>
#include<cmath>
#include<vector>
#include <queue>
#include <cstdlib>
#include<algorithm>
using namespace std;
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <stack>
#include <map>
#include <queue>
using namespace std;
struct cost
{
    int p;
    int v;
    bool operator < (const cost& a) const
    {
        return v < a.v;
    }
};
cost make(int p, int v)
{
    cost ret;
    ret.p = p;
    ret.v = v;
    return ret;
}
int main()
{
    char str[50005];
    scanf("%s", str);
    int cnt = 0;
    int len = strlen(str);
    int a, b;
    priority_queue<cost> q;
    long long ans = 0;
    for (int i = 0; i < len; i++)
    {
        cnt += str[i] == '(';
        cnt -= str[i] == ')' || str[i] == '?';
        if (str[i] == '?')
        {
            scanf("%d %d", &a, &b);
            q.push(make(i, b-a));
            ans += b;
            str[i] = ')';
        }
        if (cnt < 0 && q.empty())
        {
            ans = -1;
            break;
        }
        if (cnt < 0)
        {
            cost top = q.top();
            q.pop();
            ans = ans - top.v;
            str[top.p] = '(';
            cnt += 2;
        }
    }
    if (cnt > 0) ans = -1;
    printf("%I64d\n", ans);
    if (ans != -1) printf("%s\n", str);
    return 0;
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值