原文链接:比赛链接
- 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;
}