A. 看日出
看日出
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
在地球上美国正午时分时,法国正夕阳西下,因此如果你在美国看完日落后一分钟内赶到法国就可以再看一次日落。
Thirty很喜欢看日落,但和地球伤的人不同,他住在一个比他自己大不了多少的星球上,每次他看完一次日落想再看一次的时候,他只需要把你的椅子往前挪一段距离就可以了。
现在Thirty正坐在他星球的赤道上,赤道可以被视为一个圆,周长为m米,每次看完日落后,他都会将椅子沿着赤道往前挪动n米,再看一次日落,Thirty决定,他会一直这样重复他看日落的过程,直到他回到他第一次看日落的地方。
那么问题来了,一直赤道的周长m米和椅子每次挪动的距离n米,你能算一下Thirty总共看了多少次日落吗?(回到起点的那一次不算)
一个输入包含两个正整数n,m, n,m不超过 104
1 3 18
6
水题。。就是问你挪多少次可以挪回原点,答案就是Lcm(n, m)/n
#include<stdio.h>
int Gcd(int a, int b)
{
if(a%b==0)
return b;
return Gcd(b, a%b);
}
int main(void)
{
int T, n, m, t;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
t = n/Gcd(n, m)*m;
printf("%d\n", t/n);
}
return 0;
}
B. 光头强选举
光头强选举
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
现在有n个候选人,包括光头强,其中光头强是一号候选人。我们现在已经知道每个候选人获得了多少张选票。其中第i个候选人拥有 ai 张选票。为了赢得选举,光头强的得票数必须严格大于其他候选人。
胜利比一切都重要,所以光头强决定通过作弊来赢得选举。他会通过贿赂将给其竞争者投票的选民将选票改投给自己。那么光头强最少要贿赂几个选民才能获得选举的胜利?
接下来1行有n个数 a1 , a2 ,... an (1 ≤ai≤ 1000)表示每个候选人的票数。
4 1 8 8 8 5 5 1 11 2 8
6 4
还是水题。。。超级暴力,每次O(n)遍历找票最多的那个人,然后贿赂,直到光头强的票最多
注意要严格最大,所以每次找最大值的时候记得是>=不是>
#include<stdio.h>
int main(void)
{
int n, i, a[105], ans, temp, bet;
while(scanf("%d", &n)!=EOF)
{
ans = 0;
for(i=1;i<=n;i++)
scanf("%d", &a[i]);
while(1)
{
temp = 1, bet = a[1];
for(i=2;i<=n;i++)
{
if(a[i]>=bet)
bet = a[i], temp = i;
}
if(temp==1)
break;
ans++;
a[temp]--, a[1]++;
}
printf("%d\n", ans);
}
return 0;
}
C. yyf和女朋友玩游戏
yyf和女朋友玩游戏
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
第一行8正整数,第一把武器8个的属性。
第二行8正整数,第二把武器8个的属性。
第三行8正整数,第三把武器8个的属性。
10 10 10 10 10 10 10 9 10 10 10 10 10 10 9 10 10 10 10 10 10 9 10 10 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99 99
1 1
然后还是水题。。。。翻译过来就是给你三个序列,问哪个序列的“字典序“最大
如果都一样大输出编号最小的那个
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef struct
{
int p[12];
}Res;
Res a, b, c;
int Jud(Res a, Res b)
{
int i;
for(i=1;i<=8;i++)
{
if(a.p[i]>b.p[i])
return 1;
if(a.p[i]<b.p[i])
return 2;
}
return 1;
}
int main(void)
{
int i;
while(scanf("%d", &a.p[1])!=EOF)
{
for(i=2;i<=8;i++)
scanf("%d", &a.p[i]);
for(i=1;i<=8;i++)
scanf("%d", &b.p[i]);
for(i=1;i<=8;i++)
scanf("%d", &c.p[i]);
if(Jud(a, b)==1 && Jud(a, c)==1)
printf("1\n");
else if(Jud(b, a)==1 && Jud(b, c)==1)
printf("2\n");
else
printf("3\n");
}
return 0;
}
D. 离开迷宫
离开迷宫
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
而同时又由于事发突然,yyf没能给女神准备礼物,于是他决定在回去的路上尽量多拿点迷宫里的财宝作为礼物。当然,古代的迷宫里少不了陷阱,虽然yyf实在太强了而导致所有的陷阱只能对他的装备造成1点的耐久损失,但由于yyf本来只是打算探索迷宫,所以并没有准备太好的装备,最初的耐久值仅为x,而如果装备破破烂烂的走到女神那边是非常有失风度的。所以yyf想要知道自己能否在保证最快离开迷宫的同时装备不被破坏(耐久=0时装备会破破烂烂哦),如果可以,他希望能带走尽量多的财宝,如果不行,他就只能在离开迷宫后回趟家带上自己最好的衣服和专门为女神准备的礼物了。
给你迷宫里分布着的财宝信息以及陷阱布置。yyf希望知道自己在保证装备不变成破破烂烂的情况下最多能拿多少的财宝,如果出现多个方案,yyf希望自己的装备能尽量少被陷阱打中。
接下来2N行
前N行每行M个整数(),表示迷宫里(i,j)位置的财宝价值
后N行每行M个数字0或1,表示迷宫里(i,j)位置是否有陷阱(1为有)
(0<=N,M,x<=100)
3 3 4 1 2 9 2 6 2 3 2 1 1 1 1 0 1 0 0 0 1
1 12
多一维的dp,dp[i][j][k]表示当前走到第i行第j列,护甲值还剩k能取到的最大价值
转移:dp[i][j][k] = max(dp[i-1][j][k], dp[i][j-1][k])+a[i][j];(无陷阱)
dp[i][j][k] = max(dp[i-1][j][k+1], dp[i][j-1][k+1])+a[i][j];(有陷阱)
注意边界处理,可以初始化dp数组为一个很小的负数,然后先把dp[1][1][x]求出来再转移
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[105][105], x[105][105], dp[105][105][105];
int main(void)
{
int n, m, i, j, p, k, bet, ans;
while(scanf("%d%d%d", &n, &m, &p)!=EOF)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
scanf("%d", &a[i][j]);
}
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
scanf("%d", &x[i][j]);
}
memset(dp, -60, sizeof(dp));
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(i==1 && j==1)
{
dp[i][j][p-x[i][j]] = a[i][j];
continue;
}
for(k=1;k<=p;k++)
{
if(x[i][j]==0)
dp[i][j][k] = max(dp[i-1][j][k], dp[i][j-1][k])+a[i][j];
else
dp[i][j][k] = max(dp[i-1][j][k+1], dp[i][j-1][k+1])+a[i][j];
}
}
}
bet = -6000000;
for(k=1;k<=p;k++)
{
if(dp[n][m][k]>=bet)
bet = dp[n][m][k], ans = k;
}
if(bet==-6000000)
printf("-1\n");
else
printf("%d %d\n", ans, bet);
}
return 0;
}
E. yyf倒水
yyf倒水
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
3 5 4 3 100 64
6 24
广搜,每次有六种状态:倒空*2,倒满*2,转移*2
vis[x][y]表示状态为第一个杯子xL,第二个杯子yL
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
typedef struct
{
int x;
int y;
}Res;
Res temp, now;
queue<Res> q;
int dp[105][105], vis[105][105];
int main(void)
{
int A, B, C;
while(scanf("%d%d%d", &A, &B, &C)!=EOF)
{
memset(dp, -1, sizeof(dp));
memset(vis, 0, sizeof(vis));
while(q.empty()==0)
q.pop();
dp[0][0] = 0;
vis[0][0] = 1;
now.x = now.y = 0;
q.push(now);
while(q.empty()==0)
{
now = q.front();
q.pop();
vis[now.x][now.y] = 0;
if(now.x==C || now.y==C)
break;
if(dp[A][now.y]==-1)
{
dp[A][now.y] = dp[now.x][now.y]+1;
if(vis[A][now.y]==0)
{
temp.x = A, temp.y = now.y;
q.push(temp);
vis[A][now.y] = 1;
}
}
if(dp[now.x][B]==-1)
{
dp[now.x][B] = dp[now.x][now.y]+1;
if(vis[now.x][B]==0)
{
temp.x = now.x, temp.y = B;
q.push(temp);
vis[now.x][B] = 1;
}
}
if(dp[0][now.y]==-1)
{
dp[0][now.y] = dp[now.x][now.y]+1;
if(vis[0][now.y]==0)
{
temp.x = 0, temp.y = now.y;
q.push(temp);
vis[0][now.y] = 1;
}
}
if(dp[now.x][0]==-1)
{
dp[now.x][0] = dp[now.x][now.y]+1;
if(vis[now.x][0]==0)
{
temp.x = now.x, temp.y = 0;
q.push(temp);
vis[now.x][0] = 1;
}
}
temp.x = now.x-min(now.x, B-now.y);
temp.y = now.y+min(now.x, B-now.y);
if(dp[temp.x][temp.y]==-1)
{
dp[temp.x][temp.y] = dp[now.x][now.y]+1;
if(vis[temp.x][temp.y]==0)
{
q.push(temp);
vis[temp.x][temp.y] = 1;
}
}
temp.y = now.y-min(now.y, A-now.x);
temp.x = now.x+min(now.y, A-now.x);
if(dp[temp.x][temp.y]==-1)
{
dp[temp.x][temp.y] = dp[now.x][now.y]+1;
if(vis[temp.x][temp.y]==0)
{
q.push(temp);
vis[temp.x][temp.y] = 1;
}
}
}
if(now.x!=C && now.y!=C)
printf("impossible\n");
else
printf("%d\n", dp[now.x][now.y]);
}
return 0;
}
F. yyf之贪吃蛇大作战
没写。。感觉是个很麻烦的模拟
G. 吃巧克力
吃巧克力
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
CYF知道送自己巧克力的人非常小气,所以正多边形巧克力的边数不会超过100。现在的CYF非常想知道自己吃的正多边形巧克力到底有多少条边,你能帮他算一下吗?
一个输入有三行每行是一个点的坐标
Xi Yi
坐标之间用空格隔开
0.000000 0.000000 1.000000 1.000000 0.000000 1.000000
4
这题的三个点连起来是个三角形,
先求出三角形的外接圆半径
三角形面积用海伦公式S = sqrt(C/2*(C/2-L1)*(C/2-L2)*(C/2-L3)),其中L1, L2, L3为三边长
那么外接圆半径就是L1*L2*L3/(4*S)
之后就可以得出三角形三条边连接圆心的三个圆心角度数G1, G2, G3
答案就是2π/Gcd(G1, G2, G3)
#include<stdio.h>
#include<string.h>
#include<math.h>
typedef struct
{
double x;
double y;
}Point;
Point a, b, c;
double Len(Point a, Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double DGcd(double a, double b)
{
if(a<0.01)
return b;
if(b<0.01)
return a;
return DGcd(b, fmod(a, b));
}
int main(void)
{
double L1, L2, L3, S, C, R, G1, G2, G3, T;
while(scanf("%lf%lf%lf%lf%lf%lf", &a.x, &a.y, &b.x, &b.y, &c.x, &c.y)!=EOF)
{
L1 = Len(a, b);
L2 = Len(b, c);
L3 = Len(a, c);
C = L1+L2+L3;
S = sqrt(C/2*(C/2-L1)*(C/2-L2)*(C/2-L3));
R = L1*L2*L3/(4*S);
G1 = acos((2*R*R-L1*L1)/(2*R*R));
G2 = acos((2*R*R-L2*L2)/(2*R*R));
G3 = acos((2*R*R-L3*L3)/(2*R*R));
T = DGcd(G1, G2);
T = DGcd(T, G3);
printf("%.0f\n", 2*acos(-1.0)/T);
}
return 0;
}
H. yyf的家庭影院
yyf的家庭影院
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
yyf的女朋友们对椅子的扶手有特别的要求。有的要有左边的扶手用才开心,有的要有右边的扶手用才开心,有的要两边的扶手都给自己用才开心,还有一些觉得扶手无所谓,只要能到yyf家看电影就很开心(吃惊!)。
yyf的家庭影院的座位只有一排N个位置(电影院中两个相邻的位置之间是共用一个扶手)。现在yyf想要邀请尽可能多的女朋友来家中看电影,并且使她们感到开心,从而增加对自己的好感度。由于yyf忙于肝阴阳师,就花重金来请你来计算,他可以最多邀请几位女朋友一起来看这部电影。
第二行输入四个整数:a,b,c,d。代表yyf有a个喜欢左边扶手的女朋友,b个喜欢右边扶手的女朋友,c个同时喜欢左右两个扶手的女朋友,d个只要和来yyf家看电影就很开心的女朋友。
其中N,a,b,c,d均在1~ 1010
10 2 2 4 2 10 10 10 10 10
9 10
所有扶左手的女生全部坐左边,所有扶右手的女生全部左右边
然后中间的位置,扶两边扶手的和不扶扶手的女生交替坐
#include<stdio.h>
#include<algorithm>
using namespace std;
int main(void)
{
__int64 n, a, b, c, d, x;
while(scanf("%I64d%I64d%I64d%I64d%I64d", &n, &a, &b, &c, &d)!=EOF)
{
if(a+b>=n)
printf("%I64d\n", n);
else
{
x = n-a-b;
printf("%I64d\n", min(n, min((x+1)/2, c)+d+a+b));
}
}
return 0;
}
I. 来自星星的祝福
来自星星的祝福
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
毫无疑问,yyf就是这样的好男人。他费尽千辛万苦,找到了瞎子算命师ZJiaQ,ZJiaQ告诉他:你这辈会受到n个女孩子的赞美。
那么,请问yyf找到真爱的概率有多少?
假设每个女孩子是M个星座中任一个的概率相等。
接下来每组数据中,输入n与m(n<=1000000000000000000(18个零),m<=100)。
2 1 1 2 2
%100 %50
题目可以转化为n个小球放进m个盒子中,每个盒子至少一个小球的概率
先求出情况数
容斥:答案就是m个盒子随便放 - 其中一个盒子留空(m-1)个盒子随便放
+ 其中两个盒子留空(m-2)个盒子随便放 - … -/+所有球全放其中一个盒子里
最后总情况数(分母)为m^n,所以答案就是
其中右半部分用快速幂,左半部分组合数每次暴力就好了
答案是浮点数要尽一切可能优化精度,很显然右边是越乘越小的,左边组合数是越乘越大的
所以当乘到一个很小的数时就让他乘左边的组合数,乘到一个很大的数就继续乘右边
如果中间过程答案特别小,直接返回0
(还有这题是四舍五入,题目中说省掉小数部分。。一不小心wa了15发)
#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
double Run(__int64 n, __int64 m, __int64 k)
{
double x, ans, a, b;
a = m, b = 1;
x = 1-1.0*k/m;
ans = 1;
while(n)
{
if(n%2==1)
{
ans = ans*x;
while(ans<1000000000 && b<=k)
{
ans = ans*(a/b);
a--, b++;
}
if(ans<0.00000001)
return 0;
}
x = x*x;
n /= 2;
}
while(b<=k)
{
ans = ans*(a/b);
a--, b++;
}
return ans;
}
int main(void)
{
__int64 T, n, m, i;
double ans;
while(scanf("%I64d", &T)!=EOF)
{
while(T--)
{
ans = 1;
scanf("%I64d%I64d", &n, &m);
if(n<m)
printf("%%0\n");
else if(m==1 || m==0)
printf("%%100\n");
else if(n>=123456)
printf("%%100\n");
else
{
for(i=m-1;i>=1;i--)
{
if(i%2==0)
ans += Run(n, m, i);
else
ans -= Run(n, m, i);
}
if(ans<0 || ans>10) ans = 0;
printf("%%%.0f\n", ans*100);
}
}
}
return 0;
}
J. LJZ的ACM协会后援团
LJZ的ACM协会后援团
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
3 5 8 11
0 1 4
水题。。只要会判断质数就好了,暴力吧
#include<stdio.h>
#include<string.h>
int a[105], ans[105], k[1005] = {-1,1};
int main(void)
{
int n, i, j;
for(i=2;i<=1000;i++)
{
if(k[i])
continue;
for(j=i*i;j<=1000;j+=i)
k[j] = 1;
}
while(scanf("%d", &n)!=EOF)
{
memset(ans, 0, sizeof(ans));
for(i=1;i<=n;i++)
scanf("%d", &a[i]);
for(i=1;i<=n;i++)
{
for(j=2;j<=a[i]-2;j++)
{
if(k[j]==0 && k[a[i]-j]==1)
ans[i]++;
}
}
for(i=1;i<=n;i++)
printf("%d\n", ans[i]);
}
return 0;
}
K. 魔法王国
魔法王国
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
请问经过了m年之后,两个国家的疆域为多大。
对于每组数据输入四个整数n,m,x,y含义如题所示。其中2<=n<=1 000 000 000, 1<=m<=1 000 000 000,0<=x,y<=n。x+y=n.
1 100 1 30 70
60 40
这道题很有意思,每次将面积小的城池×2,然后让另一个城池拿n减去乘后的面积
"翻译"过来就是先×2,再取模!
所以这题就是让你求2的m次方对n取模
答案就是x*2^m%n和n-x*2^m%n,注意x是一开始面积小的那个
还有题目要求从大到小输出
#include<stdio.h>
#include<algorithm>
using namespace std;
__int64 Pow(__int64 x, __int64 y, __int64 mod)
{
__int64 ans;
ans = 1;
while(y)
{
if(y%2==1)
ans = ans*x%mod;
x = x*x%mod;
y /= 2;
}
return ans;
}
int main(void)
{
__int64 T, n, m, x, y;
while(scanf("%I64d", &T)!=EOF)
{
while(T--)
{
scanf("%I64d%I64d%I64d%I64d", &n, &m, &x, &y);
if(x>y) swap(x, y);
x = x*Pow(2ll, m, n)%n;
y = n-x;
if(x<y) swap(x, y);
printf("%I64d %I64d\n", x, y);
}
}
return 0;
}
L. YYF和女朋友玩游戏(2)
YYF和女朋友玩游戏
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
第二行包括n个数字, hi 表示主视图每一列的高度, 1≤ hi ≤20。
第三行包括m个数字, hi ’表示左视图每一列的高度, 1≤ hi ’≤20。
5 5 1 2 3 4 5 1 2 3 4 5
15
这里题解说得很对就用这个了
可以先想如何形成正视图或侧视图,那么就是二维平面,正视图(侧视图)上有多少个正方形就是有多少个正方体,然后在这个基础上侧视图(正视图)如果出现新的列(之前视图不相等)的,就要新摆放一个,否则通过平移可以看做同一列,就不需要添加正方体了,那么可以得出,最少数量正方体就是正视图或侧视图中正方形多的那个视图,把它上面的正方形数量加上另一个视图上没有出现过的所有列就是最终解。
#include<stdio.h>
int a[15], b[15];
int main(void)
{
int n, m, i, j, ans;
while(scanf("%d%d", &n, &m)!=EOF)
{
ans = 0;
for(i=1;i<=n;i++)
{
scanf("%d", &a[i]);
ans += a[i];
}
for(i=1;i<=m;i++)
{
scanf("%d", &b[i]);
ans += b[i];
}
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(a[i]==b[j] && a[i]!=-1)
{
ans -= a[i];
a[i] = b[j] = -1;
}
}
}
printf("%d\n", ans);
}
return 0;
}
M. 分西瓜
分西瓜
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 0 Accepted Submission(s): 0
A和B都非常喜欢偶数,因此他们想分西瓜以这种方式:分出来的两个西瓜的重量都是偶数,但并不要求两个西瓜是一样重的。A和B现在都非常的累,想尽快吃西瓜,你现在的任务是帮助他们分析是否能够按照他们的要求分西瓜。当然两个人都要分到西瓜。
8
YES
只要是n大于2的偶数就可以
#include<stdio.h>
int main(void)
{
int n;
while(scanf("%d", &n)!=EOF)
{
if(n!=2 && n!=0 && n%2==0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}