A-简单题
/**************************************************************
Data 2018-03-17 19:09:51
Author Ms. Wen
解题思路:考察高等数学I的知识,知道lim(v->无穷)(1+1/v)^v = e
就能轻松解出该题。最终公式为 ans = y*e^x。e^x 可以用函数exp(x)
算出。exp(x) = e^x.数C语言Math库的数学函数。
*************************************************************/
#include <stdio.h>
#include <math.h>
int main() {
int x,y,z;
int t;
scanf("%d",&t);
while(t--) {
scanf("%d%d%d",&x,&y,&z);
double ans = exp(x)*y;
if(z == 1) printf("%.1lf\n",ans);
if(z == 2) printf("%.2lf\n",ans);
if(z == 3) printf("%.3lf\n",ans);
if(z == 4) printf("%.4lf\n",ans);
if(z == 5) printf("%.5lf\n",ans);
}
return 0;
}
B-简单题2
/****************************************************
Data 2018-03-17 19:17:05
Author Ms. Wen
解题思路:lnR = 1。则R=e。可以知道该题目让求.x^e/y
e = exp(1) x^e = pow(x,e),全部用数学函数计算即可。
******************************************************/
#include <stdio.h>
#include <math.h>
int main() {
int x,y,z,t;
scanf("%d",&t);
while(t--) {
scanf("%d%d%d",&x,&y,&z);
double e = exp(1);
double ans = pow(x,e)/y;
if(z == 1) printf("%.1lf\n",ans);
if(z == 2) printf("%.2lf\n",ans);
if(z == 3) printf("%.3lf\n",ans);
if(z == 4) printf("%.4lf\n",ans);
if(z == 5) printf("%.5lf\n",ans);
}
return 0;
}
C-分元宵
/**************************************************************
Data 2018/3/23 17:58
Author Ms. Wen
解题思路:
a种馅,b种皮。共能构成a*b种元宵。考虑一张桌子上的摆放情况,一张桌子上
有d个碗,每个碗都可以放这a*b种元宵,对于一张桌子有(a*b)^d种放法,对于
c张桌子,每张桌子对应(a*b)^d种方法,则总共有(a*b)^(c*d)种放法。
注意当让取模的数为1时,答案是0。
变量含义:
a,b,c,d:a种馅,b种皮,c张桌子,每张桌子上d个碗
mod:要取模的数
方法含义:
quickPower:整数快速幂,求n的k次方取模后的值。
**********************************************************************/
#include <stdio.h>
#include <iostream>
using namespace std;
typedef long long LL;
LL a,b,c,d;
int mod;
LL quickPower(LL n,LL k) {
LL res,ans;
ans = (LL)1;
res = n;
while(k) {
if(k&1) {
ans = ans*res%mod;
}
res = res*res%mod;
k = k>>1;
}
return ans;
}
int main() {
while(~scanf("%lld%lld%lld%lld%d",&a,&b,&c,&d,&mod)) {
if(mod == 1) {
printf("0\n");
}
else {
a = a%mod;
b = b%mod;
printf("%lld\n",quickPower(a*b%mod,c*d));
}
}
return 0;
}
D-多项式乘法
/*****************************************
Data 2018-03-17 19:34:35
Author Ms. Wen
解题思路:(A*X^i) * (B*X^j) = A*B*X^(i+j)
*****************************************/
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
using namespace std;
const int maxn = 1e6;
int A[maxn],B[maxn],C[maxn];
int main() {
int n,m,x;
while(~scanf("%d%d",&n,&m)) {
for(int i = 0; i<=n ; i++) {
scanf("%d",&x);
A[i] = x; //第i项的系数为x
}
for(int i = 0; i <= m; i++) {
scanf("%d",&x);
B[i] = x; //第i项的系数为x
}
memset(C,0,sizeof(C));
for(int i = 0; i <= n; i++) {
for(int j = 0; j <= m; j++) {
C[i+j] += A[i]*B[j];
}
}
for(int i = 0; i <= m+n; i++) {
printf("%d",C[i]);
if(i != m+n) {
printf(" ");
}
}
printf("\n");
}
return 0;
}
E-圆与三角形
/**************************************************************
Data 2018-03-17 20:03:53
Author Ms. Wen
解题思路:
知道tan(A/2)*tan(B/2)+tan(B/2)*tan(C/2)+tan(A/2)*tan(C/2) = 1
题目直接就解决了,sinA*r,r是定值,让sinA最大就行,sinA最大为1.
**************************************************************/
#include <stdio.h>
int main() {
double r;
while(~scanf("%lf",&r)) {
double ans = 1 + 1*r;
printf("%.2lf\n",ans);
}
return 0;
}
F-三视图
/**************************************************************
Data 2018-03-20 21:04:48
Author Ms. Wen
解题思路:
正视图和左视图从大到小固定y,然后把每行的x和z从小到大
对于附视图,则从小到大固定z,然后每行的x从小到大。
主要还是要区别程序打出符号和自己在纸上的顺序是不一样的,
图上越左上就要在程序种越早输出。
**************************************************************/
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 1004;
int zhu[maxn][maxn]; //主视图
int zuo[maxn][maxn]; //左视图
int fu[maxn][maxn]; //俯视图
int X,Y,Z,N;
int main() {
while(~scanf("%d%d%d%d",&X,&Y,&Z,&N)) {
int x,y,z;
memset(zhu,0,sizeof(zhu));
memset(zuo,0,sizeof(zuo));
memset(fu,0,sizeof(fu));
for(int i = 0; i < N; i++) {
scanf("%d%d%d",&x,&y,&z);
zhu[y][x] = 1; //yoz面
zuo[y][z] = 1; //yox面
fu[z][x] = 1; //zox面
}
while(Y>0) {
for(int i = 1; i <= X; i++) {
if(zhu[Y][i]) {
printf("x");
}
else {
printf(".");
}
}
printf(" ");
for(int i = 1; i <= Z; i++) {
if(zuo[Y][i]) {
printf("x");
}
else {
printf(".");
}
}
printf("\n");
Y--;
}
printf("\n");
for(int i = 1; i <= Z; i++) {
for(int j = 1; j <= X; j++) {
if(fu[i][j]) {
printf("x");
}
else {
printf(".");
}
}
printf("\n");
}
}
return 0;
}
G-あなたの蛙は旅⽴っています
题目的难点在于存图,将题目给出数据按如下图所示方式存储。
/**************************************************************
Data 2018-03-22 15:28
Author Ms. Wen
解题思路:
按如图方式存储后。对于除第一行以外的其他行的元素,假如考虑
第i行第j列的元素,可以知道它可以坐标为(i-1,j-1),(i-1,j+1)和(i-2,j)
三个位置得到。
则有公式:Map[i][j] += Max(Map[i-1][j-1],Map[i-1][j+1],Map[i-2][j]
变量含义:
Map:存放题目给出的数据。
方法含义:
Max:求三个数中的最大值并返回。
**************************************************************/
#include <stdio.h>
#include <string.h>
#define inf 0x3f3f3f3f
#define maxn 3500
int Map[maxn][maxn];
void init() {
for(int i = 0; i < maxn; i++) {
for(int j = i; j < maxn; j++) {
Map[i][j] = Map[j][i] = -inf;
}
}
}
int Max(int a,int b,int c) {
if(a<b) {
a = b;
}
if(a<c) {
a = c;
}
return a;
}
int main() {
int N;
while(~scanf("%d",&N)) {
init(); //初始化
int start = N,i,j;
//先输入前N行
for(i = 1; i <= N; i++) {
for(j = start; j <= N+i-1; j+=2) { //第i行从start位置开始填数,每隔一格填一个数
scanf("%d",&Map[i][j]);
}
start--;
}
//在输入N+1 ~ 3*N-3行
start = 2;
for(; i <= 3*N-3; i++) {
for(j = start; j < 2*N; j+=2) {
scanf("%d",&Map[i][j]);
}
if(start == 2) start = 1;
else start = 2;
}
//最后输入后N行
start = 1;
for(; i <= 4*N-3; i++) {
for(j = start; j <= 2*N-start; j+=2) {
scanf("%d",&Map[i][j]);
}
start++;
}
start = N-1;
for(i = 2; i <= N; i++) {
for(j = start; j <= N+i-1; j+=2) {
Map[i][j] += Max(Map[i-1][j-1],Map[i-1][j+1],Map[i-2][j]);
}
start--;
}
start = 2;
for(; i <= 3*N-3; i++) {
for(j = start; j < 2*N; j+=2) {
Map[i][j] += Max(Map[i-1][j-1],Map[i-1][j+1],Map[i-2][j]);
}
if(start == 2) start = 1;
else start = 2;
}
start = 1;
for(; i <= 4*N-3; i++) {
for(j = start; j <= 2*N-start; j+=2) {
Map[i][j] += Max(Map[i-1][j-1],Map[i-1][j+1],Map[i-2][j]);
}
start++;
}
printf("%d\n",Map[4*N-3][N]);
}
return 0;
}
H-写真がとどいています
该题题目未给出所有音符对应的字符,需要自己百度普通五线谱。
/**
Data 2018/3/22 17:12
Author Ms. Wen
解题思路:给出出现圈的行对应的字符表。然后每次扫描一列,
只要找到圆圈,变输出表中对应的字符。否则最后输出竖线。
变量含义:
music: 存放乐谱
match: match[i]存放第i行出现的圆圈,对应什么样的字符。
**/
#include <iostream>
#include <stdio.h>
using namespace std;
const int maxn = 5010;
char music[15][maxn];
char match[]= {' ','F','E','D','C','B','A','G','F','E'};
int main() {
int n,i,j;
while(~scanf("%d ",&n)) {
for(i = 1; i <= 9; i++) {
scanf("%s",music[i]);
}
//一列一列看
for(i = 0; i < n; i++) {
for(j = 1; j <= 9; j++) {
if(music[j][i] == 'o') {
printf("%c",match[j]);
break;
}
}
if(j == 10 ) printf("|");
}
printf("\n");
}
return 0;
}
I-あなたの蛙が帰っています
/*************************************************************
Data 2018/3/23 17:04
Author Ms. Wen
解题思路:今天百度了一下才知道考察卡特兰数。对于n个数的序列,
其出战方案数多少种,设为H(n)。如果序列中第k个数是最后一个出
栈的,则k进栈前,其前(k-1)个元素均已出栈,前(k-1)个元素出
栈的序列有H(k-1)种,第k个数出栈前,其后(n-k)个元素均已出栈,
它们的出栈方案数有H(n-k)种。则第k个元素为最后一个出栈元素对应
的出栈方案数为H(k-1)*H(n-k),k又可以取遍1~n,所以可得。
H(n) = H(0)*H(n-1)+H(1)*H(n-2)*...H(n-1)*H(1)*H(n-1)*H(0);
题目要求第一个进栈的元素,不能第一个出,则在H(n)种方案中,
只有A1进A1出和剩余n-1个元素入栈出栈的情况组合是不符合要求的。
则答案就是H(n)-H(n-1).
H(n)还有这种表方法:H(n) = C(2*n,n)/(n+1);
由于该题目牵涉到除法,所以还需要求乘法逆元,题目给出的模是素数,
则可以用小费马定理求乘法逆元。
变量含义:
fac:fac[i]为i的阶乘取模后的值
方法含义:
calFac:计算fac数组
quickPower:整数快速幂求n的k次方
CatalanNumber:计算卡特兰数
*****************************************************************/
#include <iostream>
#include <stdio.h>
using namespace std;
const int maxn = 1e6+10;
const long long mod = 998244353;
long long fac[maxn];
void calFac() {
fac[0] = (long long)1;
fac[1] = (long long)1;
for(int i = 2; i < maxn; i++) {
fac[i] = fac[i-1]*i%mod;
}
}
long long quickPower(long long n,long long k) {
long long res,ans;
res = n;
ans = (long long)1;
while(k) {
if(k&1) {
ans = ans*res%mod;
}
res = res*res%mod;
k = k>>1;
}
return ans;
}
long long CatalanNumber(int n) {
long long tmp1 = quickPower(fac[n]*fac[n]%mod,mod-2);
long long tmp2 = quickPower((n+1)%mod,mod-2);
return fac[2*n]*tmp1%mod*tmp2%mod;
}
int main() {
calFac();
int n,t,Case=0;
scanf("%d",&t);
while(t--) {
scanf("%d",&n);
long long ans = (CatalanNumber(n) - CatalanNumber(n-1) + mod)%mod;
printf("Case #%d: %lld\n",++Case,ans);
}
return 0;
}
J-おみやげをまらいました
/*****************************
Data 2018-03-17 20:11:17
Author Ms. Wen
*********************************/
#include <iostream>
#include <stdio.h>
#include <map>
#include <string>
using namespace std;
map<string,string>mp;
int main() {
mp.clear();
string s1,s2;
for(int i = 0; i < 3; i++) {
cin>>s1>>s2;
mp[s2] = s1;
}
int m;
scanf("%d ",&m);
while(m--) {
getline(cin,s1);
if(mp[s1] == "") {
cout<<"Fake"<<endl;
}
else {
cout<<mp[s1]<<endl;
}
}
return 0;
}