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;
}