*特此批注: *
此题解是由三人共同完成
@马同学“你A你的 我WA我的”
@张同学Gui_qvlai
目录
*以下题解由另一位同学完成 手动@马同学
B Coin Toss
戳我.
Description
In a popular carnival game, a coin is tossed onto a table with an area that is covered with square tiles in a grid. The prizes are determined by the number of tiles covered by the coin when it comes to rest: the more tiles it covers, the better the prize. In the following diagram, the results from five coin tosses are shown:
In this example:
coin 1 covers 1 tile
coin 2 covers 2 tiles
coin 3 covers 3 tiles
coin 4 covers 4 tiles
coin 5 covers 2 tiles
Notice that it is acceptable for a coin to land on the boundary of the playing area (coin 5). In order for a coin to cover a tile, the coin must cover up a positive area of the tile. In other words, it is not enough to simply touch the boundary of the tile. The center of the coin may be at any point of the playing area with uniform probability. You may assume that (1) the coin always comes to a rest lying flat, and (2) the player is good enough to guarantee that the center of the coin will always come to rest on the playing area (or the boundary).
The probability of a coin covering a certain number of tiles depends on the tile and coin sizes, as well as the number of rows and columns of tiles in the playing area. In this problem, you will be required to write a program which computes the probabilities of a coin covering a certain number of tiles.
Input
The first line of input is an integer specifying the number of cases to follow. For each case, you will be given 4 integers m,n,t, and c on a single line, separated by spaces. The playing area consists of m rows and n columns of tiles, each having side length t. The diameter of the coin used is c. You may assume that 1≤m,n≤5000, and 1≤c<t≤1000.
Output
For each case, print the case number on its own line. This is followed by the probability of a coin covering 1 tile, 2 tiles, 3 tiles, and 4 tiles each on its own line. The probability should be expressed as a percentage rounded to 4 decimal places. Use the format as specified in the sample output. You should use double−precision floating−point numbers to perform the calculations. “Negative zeros” should be printed without the negative sign.
Separate the output of consecutive cases by a blank line.
Samples
Input
3
5 5 10 3
7 4 25 20
10 10 10 4
Output
Case 1:
Probability of covering 1 tile = 57.7600%
Probability of covering 2 tiles = 36.4800%
Probability of covering 3 tiles = 1.2361%
Probability of covering 4 tiles = 4.5239%
Case 2:
Probability of covering 1 tile = 12.5714%
Probability of covering 2 tiles = 46.2857%
Probability of covering 3 tiles = 8.8293%
Probability of covering 4 tiles = 32.3135%
Case 3:
Probability of covering 1 tile = 40.9600%
Probability of covering 2 tiles = 46.0800%
Probability of covering 3 tiles = 2.7812%
Probability of covering 4 tiles = 10.1788%
解析:我们解这个题的思路就是求硬币在哪些区域会压到几块方格,然后把这些区域的面积加起来除以总面积,便是硬币压到对应方格数的概率。
我们求这个面积的时候都是找与线相切时的位置的。然后找出边长即可求得面积。还有一点别再计算的过程中迷糊了就是他给的是硬币的直径!!
- 压两块
-
压三或四块
-
压一块
注意输出的格式: -
tile tiles;
-
tile后有俩空格
Code:
#include<bitsdc++.h>
#pragma GCC optimize(2)
using namespace std;
typedef long long ll;
const int N = 20;
const double pi = acos(-1.0);
int x,k=0,q;
double m,n,t,c;
int main() {
cin>>x;
q = x;
while(x--) {
scanf("%lf%lf%lf%lf",&m,&n,&t,&c);
double s = n*m*t*t;
double s2 = c*(t-c)*(2*m*n-n-m)+c*(c/2.0)*2*(m+n-2);
double s4 = pi*c*c/4.0*(m-1)*(n-1);
double s3 = (m-1)*(n-1)*c*c-s4;
double s1 = s - s2 - s3 - s4;
printf("Case %d:\n",++k);
printf("Probability of covering 1 tile = %.4lf%\n",s1/s*100);
printf("Probability of covering 2 tiles = %.4lf%\n",s2/s*100);
printf("Probability of covering 3 tiles = %.4lf%\n",s3/s*100);
printf("Probability of covering 4 tiles = %.4lf%\n",s4/s*100);
if(k!=q) putchar('\n');
}
return 0;
}
*以下由另一位同学完成 手动@张同学
其他题目题解
以下题解由本人完成,水平有限
O. Necklace
题目意思:
某部落的人们用一些稀有的粘土制作直径相等的圆形陶瓷圆盘。项链是通过连接一个或多个光盘而形成的。下图显示了一条由4个圆盘制成的项链。它的长度是每个圆盘直径的4倍。
每个圆盘的厚度都是固定的。用V粘土的直径D与体积之间存在以下关系:
其中V0是烘烤过程中消耗的体积,单位为V。V≤V0时,不得制作陶瓷盘。例如,让Vtotal=10,V0=1。如果我们用它制作1个圆盘,V=Vtotal=10,D=0.9。如果我们将粘土分为2部分,则每个零件的体积V=Vtotal/2=5,形成的每个圆盘的直径为D’=0.35−1负极—√=0.6,因此,以这种方式形成的项链长度为1.2。
根据上述示例,随着光盘数量的变化,项链的长度显然不同。请编写一个程序,计算一个人应该制作的光盘数量,使项链形成的时间最长。
输入
每一输入线包含两个数字,如上文所定义的Vtotal(0<Vtotal≤60000)和V0(0<V0≤600)。输入端部的情况为Vtotal=V0=0。
输出
每一行输出应给出一个应该制作的光盘数量,以便形成的项链最长。如果此数字不是唯一的,或者根本无法形成项链,则输出“0”。
题目解析:
设粘土被分为n份,则项链的长度为n×D,f(n)=n×D=n×0.3×sqrt(Vt/n-V0)。由于根号运算会有一定的误差,所以,考虑消除根号,f(n)/0.3=n×sqrt(Vt/n-V0),得新的方程式 g(n)=(f(n)/0.3)2=n2×(Vt/n-V0)=n×Vt-n2×V0,经过上述过程,所要求的答案成为使得g(n)最大的值。
对g(n)求导,g(n)’=Vt-2×n×V0。在导函数g(n)'有极值。所以,n=Vt/(2×V0)。
由于份数必须是整数,所以,在计算n之后,要判断最接近n的整数。如下面程序中所示,计算n和对n向下取整的差,如果等于0.5,表示有两个整数解,输出0;如果等于0.5,则输出n向下取整的值;否则输出n向上取整的值。
AC代码:
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cstdio>
#include <list>
#include <deque>
#include <set>
#include <vector>
#include <map>
#include <cstring>
#include <iomanip>
#define max(a,b) (a>b?a:b)
#define ll long long
using namespace std;
const int mod=1e9+7;
const int maxn=1e6+5;
int main() {
double vt,v0;
while(scanf("%lf%lf",&vt,&v0)!=EOF) {
if(vt==0||v0==0)
break;
if(vt<=v0)
printf("0\n");
else if(vt<=2*v0)
printf("1\n");
else {
double m=vt/2*v0;
if(m-(int)m==0.5)
printf("0\n");
else if(m-(int)m<0.5)
printf("%d\n",(int)m);
else
printf("%d\n",(int)m+1);
}
}
return 0;
}
P. Symmetric Matrix
P. Symmetric Matrix
题目意思:
给你一个正方形矩阵M,这个矩阵的元素是Mij:{0<i<n,0<j<n}。在这个问题中,你必须找出给定的矩阵是否对称。
定义:对称矩阵是这样一个矩阵,它的所有元素都是非负的,并且相对于这个矩阵的中心对称。任何其他矩阵都被认为是非对称的。例如:
你所要做的就是找出矩阵是否对称。输入中给出的矩阵元素为−232≤Mij≤232和0<n≤100。
输入
第一行输入包含测试用例数T≤300。然后T个测试用例按照下面的方式进行描述。每个测试用例的第一行包含n—方阵的维数。然后n行跟在包含行i的每个行后面。行正好包含n个元素,元素之间用空格分隔。第i行的第j个数是你必须处理的矩阵的元素Mij。
输出
对于每个测试用例,输出一行“test#t:S”。其中t是从1开始的测试编号。如果矩阵是对称的,而在其他情况下是非对称的,则S线等于“对称的”。
问题大致分析:
判定给定的矩阵是否中心对称问题,看程序代码。
AC代码:
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cstdio>
#include <list>
#include <deque>
#include <set>
#include <vector>
#include <map>
#include <cstring>
#include <iomanip>
#define max(a,b) (a>b?a:b)
#define ll long long
using namespace std;
const int mod=1e9+7;
const int maxn=1e6+5;
ll a[101][101];
int main() {
int t,n;
char c[2];
cin>>t;
for(int k=1; k<=t; k++) {
scanf("%s%s%d",c,c,&n);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
scanf("%lld",&a[i][j]);
int flag=1;
for(int i=0; i<n&&flag; i++) {
for(int j=0; j<n; j++)
if(a[i][j]<0||a[i][j]!=a[n-i-1][n-j-1]) {
flag=0;
break;
}
}
printf("Test #%d: ",k);
if(flag)
printf("Symmetric.\n");
else
printf("Non-symmetric.\n");
}
return 0;
}
J. Is This Integration?
题目意思:
在下图中,您可以看到一个正方形abc,其中AB=BC=CD=DA=a。以四个顶点a、B、C、D为中心,以a为半径绘制四条弧。以A为中心绘制的弧,从相邻顶点B开始,到相邻顶点D结束。所有其他弧都以类似的方式绘制。以这种方式创建三种不同形状的区域。如果这些不同形状的区域存在,则必须确定总面积。
输入
输入文件的每一行都包含一个浮点数a(0≤a≤10000),表示正方形一侧的长度。输入在文件末尾终止。
输出
对于每行输入,在一行中输出三种类型区域的总面积(在上图中填充不同的图案)。
这三个数字当然是浮点数,小数点后有三位数字。第一个数字表示条纹区域的面积,第二个数字表示虚线区域的总面积,第三个数字表示其余区域的面积。
题目解析:
本题给出正方形的边长a,要求计算三种不同阴影部分的总面积。如图所示,做辅助线画一等边三角形,并且三种不同阴影部分面积分别用x,y和z表示。
则x+4y+4z=a2(正方形面积);x+3y+2z=π*a2/4(四分之一圆的面积);而z的面积是正方形面积去掉等边三角形的面积和两个扇形的面积,其中扇形是正方形的边和等边三角形的边构成,而两个扇形的面积为六分之一圆面积,而等边三角形面积为sqrt(3)×a2/4,即,z=a2-sqrt(3)×a2/4-π×a2/6。将z代入,得 y=[(-1+sqrt(3)/2)+π/12]×a2, x=(1+sqrt(3)+π/3)×a2。
AC代码:
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cstdio>
#include <list>
#include <deque>
#include <set>
#include <vector>
#include <map>
#include <cstring>
#include <iomanip>
#define max(a,b) (a>b?a:b)
#define ll long long
#define pi 3.141592653589793
using namespace std;
const int mod=1e9+7;
const int maxn=1e6+5;
int main() {
double a;
double x,y,z;
while(scanf("%lf",&a)!=EOF){
x=a*a*(1+pi/3-sqrt(3.0));
y=a*a*(pi/3+2*sqrt(3.0)-4);
z=a*a*(-2*pi/3+4-sqrt(3.0));
printf("%.3lf %.3lf %.3lf\n",x,y,z);
}
return 0;
}
L. Euclid Problem
题目意思:
从欧几里德可知,对于任何正整数A和B,都存在这样的整数X和Y,即AX+BY=D,其中D是A和B的最大公约数。问题是找到给定A和B对应的X、Y和D。
输入
输入将由一组带有整数a和B的行组成,用空格隔开(a,B<1000000001)。
输出
对于每个输入行,输出行应由三个整数X、Y和D组成,用空格隔开。如果存在多个这样的X和Y,则应输出| X |+| Y |为最小值的对。如果有多个X和Y满足最小条件,则输出X≤Y的对。
题目分析:
扩展欧几里得
AC代码:
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cstdio>
#include <list>
#include <deque>
#include <set>
#include <vector>
#include <map>
#include <cstring>
#include <iomanip>
#define max(a,b) (a>b?a:b)
#define ll long long
#define pi 3.141592653589793
using namespace std;
const int mod=1e9+7;
const int maxn=1e6+5;
ll exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){
x=1;
y=0;
return a;
}
ll t=exgcd(b,a%b,x,y);
ll x1=x;
ll y1=y;
x=y1;
y=x1-(a/b)*y1;
return t;
}
int main() {
ll a,b,x,y,d;
while(cin>>a>>b){
d=exgcd(a,b,x,y);
printf("%d %d %d\n",x,y,d);
}
return 0;
}
C. Bode Plot
题目意思:
考虑下面的交流电路。我们假设电路处于稳态。因此,节点1和2处的电压由v1=VScoswt和v2=VRcos(wt+θ)给出,其中VS是源的电压,w是频率(以弧度/秒为单位),t是时间。VR是通过电阻器的电压降的大小,θ是其相位。
你要写一个程序来确定不同w值的VR。你需要两个电学定律来解决这个问题。第一个是欧姆定律,表示v2=iR,其中i是电路中的电流,顺时针方向。第二个是i=Cd/dt(v1−v2),它将电流与电容器两侧的电压联系起来。“d/dt”表示相对于t的导数。
输入
输入将由一行或多行组成。第一行包含三个实数和一个非负整数。实数的顺序是VS,R,C。整数n是测试用例的数量。以下n行输入每行有一个实数。每一个数字都是角频率,w。
输出
对于输入中的每个角频率,您要在一行上输出相应的VR。每个VR值输出应四舍五入到小数点后的三位数字。
题目解析:
AC代码:
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cstdio>
#include <list>
#include <deque>
#include <set>
#include <vector>
#include <map>
#include <cstring>
#include <iomanip>
#define max(a,b) (a>b?a:b)
#define ll long long
using namespace std;
const int mod=1e9+7;
const int maxn=1e6+5;
#define pi 3.141592653589793
int main() {
int n;
double ans,vs,r,c,w;
scanf("%lf%lf%lf%d",&vs,&r,&c,&n);
for(int i=0; i<n; i++) {
scanf("%lf",&w);
ans=c*r*w*vs/sqrt(1+c*c*r*r*w*w);
printf("%.3lf\n",ans);
}
return 0;
}
D. Homogeneous squares
题目意思:
假设你有一个大小为n的正方形,被分成n×n个位置,就像棋盘一样。两个位置(x1,y1)和(x2,y2),其中1≤x1,y1,x2,y2≤n,如果它们占用不同的行和列,即x1≠x2和y1≠y2,则称为“独立”。更一般地说,如果n个位置是成对独立的,则称为独立的。因此有n!选择n个独立位置的不同方法。
进一步假设在这样一个n×n平方的每个位置都写了一个数字。如果写在n个独立位置上的数字之和相同,则无论位置如何选择,该平方称为“齐次”。写一个程序来确定一个给定的正方形是否是齐次的!
输入
输入包含几个测试用例。
每个测试用例的第一行包含一个整数n(1≤n≤1000)。接下来的n行中的每一行都包含n个数字,由一个空格字符分隔。每个数字都是区间[-1000000]中的整数。
最后一个测试用例后跟一个零。
输出
对于每个测试用例输出,不管指定的平方是否均匀。遵循示例输出中显示的格式。
题目分析:
由这一局部解递推出规律:对于一个n ×n方针,只要它的所有的(n-1)×(n-1)子方针是homogeneous的,则该n x n方阵是homogeneous的;进一步递推可得,只要该n × n方阵的所有2 × 2的子方阵符合两对角线相加相等,该n×n方阵是homogeneous的。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int a[1001][1001];
int main() {
int n;
int flag,i,j;
while(scanf("%d",&n)!=EOF&&n!=0) {
flag=1;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
scanf("%d",&a[i][j]);
for(i=1; i<n; i++)
for(j=1; j<n; j++)
if(a[i][j]+a[i+1][j+1]!=a[i][j+1]+a[i+1][j]) {
flag=0;
break;
}
if(flag)
printf("homogeneous\n");
else
printf("not homogeneous\n");
}
return 0;
}
F. 数的拆分
题目比较简单,直接贴代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a;
int x,y,z;
cin>>a;
x=a/100;
y=a/10%10;
z=a%10;
cout<<x+y+z;
return 0;
}
N. 498-bis
题目意思:
在“在线法官习题集档案”中,我发现了一道非常有趣的题,题为“多项式波利”。坦白说,我没有解决这个问题,但我从中衍生出这个问题。
这个问题中的一切都是498的导数。尤其是,498是“。。。旨在帮助你记住。。。基本的代数技能,让世界变得更美好等等。这个问题旨在帮助你记住基本的代数推导技巧,提高世界变得更好的速度,等等。
在498,你必须计算多项式的值
a0xn+a1xn−1+⋯+a−1x+a
在这个问题中,你应该计算它的导数。记住导数的定义是
a0nxn−1+a1(n−1)xn−2+⋯+an−1
所有的输入和输出数据都将拟合成整数,即其绝对值将小于231。
输入
你的程序应该接受偶数行的文本。每对线代表一个问题。第一行将包含一个整数-x的值。第二行将包含整数a0,a1,…,an−1,an的列表,它们表示一组多项式系数。
输入由终止。
输出
对于每对线,您的程序应该计算给定值x的多项式导数,并在一行中输出它。
题目分析:
AC代码:
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cstdio>
#include <list>
#include <deque>
#include <set>
#include <vector>
#include <map>
#include <cstring>
#include <iomanip>
#define max(a,b) (a>b?a:b)
#define ll long long
#define pi 3.141592653589793
using namespace std;
const int mod=1e9+7;
const int maxn=1e6+5;
int a[maxn];
int main() {
int t,n;
char c;
while(scanf("%d",&t)!=EOF){
ll sum=0;
ll ans=0;
while(scanf("%d",&n)!=EOF){
ans=ans*t+sum;
sum=sum*t+n;
scanf("%c",&c);
if(c=='\n')
break;
}
cout<<ans<<endl;
}
return 0;
}