A
一句话题意:求出平面上一个三角形的外心坐标
题解:列出三角形两条边的垂直平分线方程,联立解方程组即可
代码:
#include<stdio.h>
double A,B,C,D,E,F,ax,bx,cx,ay,by,cy,xc1,yc1,xc2,yc2,dy1,dx1,dy2,dx2;
int main(){
scanf("%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy);
xc1=(ax+bx)*0.5;
yc1=(ay+by)*0.5;
xc2=(ax+cx)*0.5;
yc2=(ay+cy)*0.5;
dx1=by-ay;
dy1=ax-bx;
dx2=cy-ay;
dy2=ax-cx;
A=-dy1;
B=dx1;
D=-dy2;
E=dx2;
C=-dy1*xc1+dx1*yc1;
F=-dy2*xc2+dx2*yc2;
// printf("%.3f %.3f %.3f\n%.3f %.3f %.3f\n",A,B,C,D,E,F);
printf("%.3f %.3f\n",(C*E-B*F)/(A*E-B*D),(A*F-C*D)/(A*E-B*D));
}
B
一句话题意:打印图形化的汉诺塔移动过程
题解:类似汉诺塔移动步骤的递归解法,只不过需要把每一步移动步骤进行图形化显示。算清楚图形长宽,以及如何显示柱子、盘子,在对应位置显示正确的字符即可
#include<stdio.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
int n,s[3][20],t[3],tot;
void printhanoi(){
fo(i,1,3*(n+n+1)+4) putchar('.');
putchar('\n');
fd(i,n+1,1){
putchar('.');
fo(j,0,2){
if (t[j]<i){
fo(k,1,n) putchar('.');
putchar('|');
fo(k,1,n) putchar('.');
}else{
fo(k,1,n-s[j][i]) putchar('.');
fo(k,1,s[j][i]) putchar('*');
putchar('*');
fo(k,1,s[j][i]) putchar('*');
fo(k,1,n-s[j][i]) putchar('.');
}
putchar('.');
}
putchar('\n');
}
tot++;
if (tot>>n) return;
fo(i,1,3*(n+n+1)+4) putchar('-');
putchar('\n');
}
void hanoi(int n,int a,int b){
if (n==0) return;
hanoi(n-1,a,3-a-b);
s[b][++t[b]]=s[a][t[a]--];
printhanoi();
hanoi(n-1,3-a-b,b);
}
int main(){
scanf("%d",&n);
fd(i,n,1) s[0][++t[0]]=i;
printhanoi();
if (n&1) hanoi(n,0,1);else hanoi(n,0,2);
return 0;
}C
一句话题意:电视循环播放50个时刻节目和10时刻广告,求t1t2时刻有多少个时刻是节目n时刻有多少个时刻是节目的问题。这个问题装修要将60个时刻作为一个周期就很好计算出来。
题解:转化为1
#include<stdio.h>
long long l,r;
long long ask(long long n){
long long ans=0;
ans=n/60*50;
n%=60;
if (n>50) n=50;
return ans+n;
}
int main(){
while (scanf("%lld%lld",&l,&r)==2){
printf("%lld\n",ask(r)-ask(l-1));
}
return 0;
}D
一句话题意:不难看出路径长度不影响答案。需要求出从DAG起点到终点的路径条数
题解:拓扑排序+动态规划即可。f[i]表示从起点到i的不同路径方案数
#include<stdio.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
int n,m,xx,yy,zz,q[110000],f[110000],he,ta,rd[110000],et,be[110000];
long long d[110000],oo,te;
const int p=20010905;
struct edg{
int y,ne;
long long z;
}e[220000];
inline void add_edge(int x,int y,int z){
e[++et].y=y;
e[et].ne=be[x];
e[et].z=z;
be[x]=et;
rd[y]++;
}
int main(){
scanf("%d%d",&n,&m);
fo(i,1,m){
scanf("%d%d%d",&xx,&yy,&zz);
add_edge(xx,yy,zz);
}
q[he=ta=1]=1;
oo=0x3fffffff;oo*=oo;
fo(i,2,n) d[i]=oo;
while (he<=ta){
int &x=q[he];
for(int i=be[x];i;i=e[i].ne){
rd[e[i].y]--;
te=d[x]+e[i].z;
if (te<d[e[i].y]) d[e[i].y]=te;
if (!rd[e[i].y]){
q[++ta]=e[i].y;
}
}
he++;
}
f[1]=1;
fo(t,1,ta){
int &x=q[t];
for(int i=be[x];i;i=e[i].ne){
f[e[i].y]+=f[x];
if (f[e[i].y]>=p) f[e[i].y]-=p;
}
}
printf("%lld\n",f[n]);
return 0;
}E
一句话题意:根据多门课程的平时、期中、期末成绩和比例算出G总GPA
题解:按题意模拟即可
#include<stdio.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
int n,ty;
double num,s1,p1,s2,p2,s3,p3;
long double fz,fm;
int main(){
scanf("%d",&n);
fo(i,1,n){
scanf("%d%lf%lf%lf%lf%lf%lf%lf",&ty,&num,&s1,&p1,&s2,&p2,&s3,&p3);
if (ty>1) continue;
fm+=num;
fz+=num*(int(s1*p1+s2*p2+s3*p3+0.5));
}
printf("%.2f\n",double(fz/fm));
return 0;
}F
题目本身就是一句话题意~
题解:利用斐波那契数列的性质,可以推出n为偶数,答案为1,否则答案为-1。可以利用斐波那契数列递推性质证明
#include<stdio.h>
#include<string.h>
char s[11000];
int n;
int main(){
scanf("%s",s+1);
n=strlen(s+1);
if ((s[n]-'0')&1) putchar('-');
printf("1\n");
return 0;
}G
一句话题意:给定一个初始只包含一个数的多重集合n,两人轮流操作,每次操作可以从集合中取出一个数,将其分解为它的两个非1因数,并加入集合中。问先手还是后手先无法操作。
题解:可以发现,胜负只和n可以因数分解为多少个质因子有关。奇数个则先手无法操作,否则后手无法操作
#include<stdio.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
int cnt,n;
int main(){
scanf("%d",&n);
for(int i=2;i*i<=n;i++) if (n%i==0){
while (n%i==0) n/=i,cnt++;
}
if (n>1) cnt++;
// printf("%d\n",cnt);
if (cnt&1) printf("Nancy\n");else printf("Johnson\n");
return 0;
}H
Hello World问题
#include<stdio.h>
int main(){
printf("\"Happy New Year!\"\n");
}I
一句话题意:求解iloveyou在输入字符串中作为子序列出现多少次(大小写不敏感)
题解:先将字符串统一大小写。然后可以用简单的动态规划求解。枚举输入字符串的每个字符s[i],f[j]表示到当前字符匹配到iloveyou的第j个字符的s[1..i]中的子序列数目,根据当前字符s[i]简单转移即可
#include<stdio.h>
#include<string.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
char s[1100000];
const int p=20010905;
int n,f[9];
int main(){
scanf("%s",s+1);
n=strlen(s+1);
fo(i,1,n) if (s[i]>='A'&&s[i]<='Z') s[i]+='a'-'A';
f[0]=1;
fo(i,1,n)
switch(s[i]){
case 'u':f[8]+=f[7];if (f[8]>=p) f[8]-=p;break;
case 'o':f[7]+=f[6];if (f[7]>=p) f[7]-=p;f[3]+=f[2];if (f[3]>=p) f[3]-=p;break;
case 'y':f[6]+=f[5];if (f[6]>=p) f[6]-=p;break;
case 'e':f[5]+=f[4];if (f[5]>=p) f[5]-=p;break;
case 'v':f[4]+=f[3];if (f[4]>=p) f[4]-=p;break;
case 'l':f[2]+=f[1];if (f[2]>=p) f[2]-=p;break;
case 'i':f[1]+=f[0];if (f[1]>=p) f[1]-=p;break;
}
printf("%lld\n",f[8]);
return 0;
}J
一句话题意:三维地图走迷宫最短路问题
题解:简单用8个方向的bfs求解即可
#include<stdio.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
char s[110][110][110];
int nx,ny,nz,n,qx[1100000],qy[1100000],qz[1100000],qs[1100000],he,ta;
const int dx[6]={1,-1,0,0,0,0};
const int dy[6]={0,0,1,-1,0,0};
const int dz[6]={0,0,0,0,1,-1};
bool vis[110][110][110];
int main(){
scanf("%d",&n);
fo(i,1,n) fo(j,1,n) scanf("%s",s[i][j]+1);
he=ta=1;
qx[1]=qy[1]=qz[1]=qs[1]=1;vis[1][1][1]=1;
while (he<=ta){
fo(i,0,5){
nx=qx[he]+dx[i];
ny=qy[he]+dy[i];
nz=qz[he]+dz[i];
if (nx>0&&ny>0&&nz>0&&nx<=n&&ny<=n&&nz<=n&&s[nx][ny][nz]=='.'&&!vis[nx][ny][nz]){
qs[++ta]=qs[he]+1;
qx[ta]=nx;
qy[ta]=ny;
qz[ta]=nz;
// printf("%d %d %d:%d\n",nx,ny,nz,qs[he]+1);
vis[nx][ny][nz]=1;
if (nx==n&&ny==n&&nz==n){
printf("%d\n",qs[ta]);
return 0;
}
}
}
he++;
}
printf("-1\n");
return 0;
}
京公网安备 11010502036488号