比赛链接戳我……
A题
sumTime小时分给d天,每天的时间有个最大最小值,看看能不能分。
第一步无非最小值加一下最大值加一下判断成立不成立。
第二步逗了……本来应该是把总得差拿最大值凑够剩下的给下一天……结果直接忽略了……WA一发……
AC代码
#include <iostream>
using namespace std;
struct day
{
int minn;
int maxn;
int cha;
int t;
};
int main()
{
int i, d,hour,sum1=0,sum2=0;
cin>>d>>hour;
day count[d];
for(i=0;i<d;i++)
{
cin>>count[i].minn>>count[i].maxn;
sum1+=count[i].minn;
sum2+=count[i].maxn;
count[i].cha=count[i].maxn-count[i].minn;
count[i].t=count[i].minn;
}
if(hour<sum1||hour>sum2) cout<<"NO"<<endl;
else
{
cout<<"YES"<<endl;
int j=0;
int sum3=hour-sum1;
while(sum3>0)
{
count[j].t+=count[j].cha;
sum3-=count[j].cha;
if(sum3>=0)
j++;
}
count[j].t=count[j].t+sum3;
for(i=0;i<d;i++)
cout<<count[i].t<<" ";
}
return 0;
}
B题
动态规划,这周没事就得多练练了,属于有思路代码就是不熟练,死坑死坑的……
题目的意思是从左上走到右下角↘,沿途乘积零最少。能出零的数因数里面一定会带2或者5,那就搜最少的就好了,注意如果有0就走0就对了
AC代码
#include <cstdio>
#include <cstring>
const int maxn = 1017;
int m[2][maxn][maxn];
int dp[2][maxn][maxn];
int vis[2][maxn][maxn];
int n;
int solve(int mark)
{
vis[mark][1][1] = 0;
dp[mark][1][1] = m[mark][1][1];
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(i==1 && j==1)
continue;
if(i == 1)
{
dp[mark][i][j] = dp[mark][i][j-1] + m[mark][i][j];
vis[mark][i][j] = 1;
}
else if(j == 1)
{
dp[mark][i][j] = dp[mark][i-1][j] + m[mark][i][j];
vis[mark][i][j] = 0;
}
else
{
int tt1 = dp[mark][i-1][j];
int tt2 = dp[mark][i][j-1];
if(tt1 < tt2)
{
dp[mark][i][j] = tt1 + m[mark][i][j];
vis[mark][i][j] = 0;
}
else
{
dp[mark][i][j] = tt2 + m[mark][i][j];
vis[mark][i][j] = 1;
}
}
}
}
return dp[mark][n][n];
}
void print(int mark, int x, int y)
{
if(x==1 && y==1)
return ;
if(vis[mark][x][y] == 0)
{
print(mark,x-1,y);
printf("D");
}
else
{
print(mark,x,y-1);
printf("R");
}
}
int main()
{
int x, y;
while(~scanf("%d",&n))
{
int tt, t1, t2;
memset(vis,0,sizeof(vis));
memset(m,0,sizeof(m));
int flag = 0;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
scanf("%d",&tt);
if(tt == 0)
{
flag = 1;
x = i;
y = j;
continue;
}
t1 = t2 = tt;
while(t1%2 == 0)
{
t1/=2;
m[0][i][j]++;
}
while(t2%5 == 0)
{
t2/=5;
m[1][i][j]++;
}
}
}
int ans1 = solve(0);
int ans2 = solve(1);
int mark = 0;
int ans = 0;
if(ans1 < ans2)
{
ans = ans1;
mark = 0;
}
else
{
ans = ans2;
mark = 1;
}
if(flag && ans > 1)
{
printf("1\n");
for(int i = 2; i <= x; i++)
{
printf("D");
}
for(int j = 2; j <= n; j++)
{
printf("R");
}
for(int i = x+1; i <= n; i++)
{
printf("D");
}
printf("\n");
continue;
}
printf("%d\n",ans);
print(mark, n, n);
printf("\n");
}
return 0;
}
c题
横、竖、斜连在一起即为WIN,麻烦在判断违规的情况实在是太多了……
AC代码
#include <iostream>
using namespace std;
char a[3][3];
bool win(char s)
{
if((a[0][0] == s&&a[0][1]==s&&a[0][2] == s)||
(a[1][0] == s&&a[1][1]==s&&a[1][2] == s)||
(a[2][0] == s&&a[2][1]==s&&a[2][2] == s)||
(a[0][0] == s&&a[1][0]==s&&a[2][0] == s)||
(a[0][1] == s&&a[1][1]==s&&a[2][1] == s)||
(a[0][2] == s&&a[1][2]==s&&a[2][2] == s)||
(a[0][0] == s&&a[1][1]==s&&a[2][2] == s)||
(a[0][2] == s&&a[1][1]==s&&a[2][0] == s))return 1;
return 0;
}
int main()
{
int i,j,f = 0,s = 0;
bool full = 1;
for(i = 0;i < 3;i ++)
{
for(j = 0;j < 3;j ++)
{
cin>>a[i][j];
if(a[i][j] =='.') full = 0;
else if(a[i][j] == 'X') f ++;
else s ++;
}
}
if(f == s||f == s + 1)
{
if(full)
{
if(win('X')) {if(f == s+1){if(win('0'))cout<<"illegal"<<endl;else cout<<"the first player won"<<endl;}else cout<<"illegal"<<endl;}
else if(win('0')) {if(f==s+1)cout<<"illegal"<<endl;else cout<<"the second player won"<<endl;}
else cout<<"draw"<<endl;
}
else
{
if(win('X')) {if(f == s+1){if(win('0'))cout<<"illegal"<<endl;else cout<<"the first player won"<<endl;}else cout<<"illegal"<<endl;}
else if(win('0')) {if(f==s+1)cout<<"illegal"<<endl;else cout<<"the second player won"<<endl;}
else if(f == s) cout<<"first"<<endl;
else cout<<"second"<<endl;
}
}
else cout<<"illegal" <<endl;
}
D题
给出三点的坐标——>海伦公式求外接圆半径——>余弦公式求圆周角——>圆周角的最大公约数即为等分圆的角度——>求面积
双精度实数求最大公约数的方法第一次见……涨姿势!!
AC代码
#include <iostream>
#include<cstdio>
#include<cmath>
#define eps 1e-4
const double pi = 3.1415926535;
using namespace std;
struct point
{
double x,y;
}p[3];
double dis(int i, int j) {
double x = p[i].x - p[j].x,y = p[i].y - p[j].y;
return sqrt(x * x + y * y);
}
double hailun(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);
}
double Angle(double a,double b,double c)
{
return acos((a*a+b*b-c*c)/(2*b*a));
}
double gcd(double a,double b)
{
if(b+eps>0&&b-eps<0)
return a;
if(a+eps>0&&a-eps<0)
return b;
return gcd(b,fmod(a,b));
}
int main ()
{ double a,b,c,angle1,angle2,angle3,angle;
for (int i = 0; i < 3; i++)
cin>>p[i].x>>p[i].y;
a = dis(0, 1);
b = dis(1, 2);
c = dis(2, 0);
double r=hailun(a,b,c);
angle1=Angle(r,r,a);
angle2=Angle(r,r,b);
angle3=2*pi-angle1-angle2;
angle=gcd(angle1,gcd(angle2,angle3));
double ans;
ans=0.5*r*r*sin(angle)*(2*pi/angle);
printf("%.6lf\n",ans);
return 0;
}
E题
给出字符串由()?三个元素组成,给出?变成(和)所需花费,求能不能转换,能的话求最少花费……
优先队列为容器,贪心思想;
#include<iostream>
#include<queue>
using namespace std;
struct defio
{
int p,pos;
}tmp;
priority_queue<defio> q;
bool operator<(const defio &a,const defio &b) {return a.p<b.p;}
int main()
{
string s;
cin>>s;
long long a,b,l=0,cost=0;
for(int i=0;i<s.size();i++)
{
if(s[i]=='(') l++;
else if (s[i]==')') l--;
else
{
cin>>a>>b;
tmp.p=b-a; tmp.pos=i;
q.push(tmp);
s[i]=')';
l--;
cost+=b;
}
if(l<0)
{
if(q.empty()) break;
tmp=q.top();
q.pop();
cost-=tmp.p;
s[tmp.pos]='(';
l+=2;
}
}
if(l!=0)cout<<-1<<endl;
else
{
cout<<cost<<endl;
cout<<s<<endl;
}
while(!q.empty())
q.pop();
return 0;
}