计概杂烩2021
2021期末
A+B Problem?
#include <stdio.h>
int main(void) {
int a,b,d;char c;scanf("%d%c%d",&a,&c,&b);
if(c=='+') d=a+b;
if(c=='-') d=a-b;
if(c=='*') d=a*b;
if(c=='/') d=a/b;
printf("%d\n",d);
return 0;
}
乘坐北京地铁
#include <stdio.h>
int main(void) {
int n,k;scanf("%d%d",&k,&n);
double ans;
if(n<=6) ans=3;
else if(n<=12) ans=4;
else if(n<=22) ans=5;
else if(n<=32) ans=6;
else{
if((n-32)%10==0) ans=(n-32)/10+6;
else ans=(n-32)/10+7;
}
if(k>=150) ans*=0.5;
else if(k>=100) ans*=0.8;
printf("%.2lf\n",ans);
return 0;
}
细菌共生
#include <stdio.h>
int a[4000];
int main(void) {
int n,ans=0,cnt=0;scanf("%d",&n);
for(int i=1;i<=n;++i) {scanf("%d",&a[i]);if(ans<a[i]) ans=a[i];}
for(int i=1;i<=n;++i)
if(a[i]<=ans/2)
++cnt;
printf("%d\n",n-cnt);
return 0;
}
机试排名
#include <stdio.h>
int a[400],b[400];
int main(void) {
int n;scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d%d",&a[i],&b[i]);
for(int i=1;i<n;++i)
for(int j=i+1;j<=n;++j)
if(b[i]<b[j]||(b[i]==b[j]&&a[i]>a[j]))
{int tmp=a[i];a[i]=a[j];a[j]=tmp;
tmp=b[i];b[i]=b[j];b[j]=tmp;}
for(int i=1;i<=n;++i)
printf("%d\n",a[i]);
return 0;
}
解密文本(encode)
#include <stdio.h>
#include <string.h>
int n,a[200];
char c[200];
int main(void) {
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
scanf("\n%s",c);int l=strlen(c);
for(int i=1;i<=n;++i)
printf("%c",a[i]+c[(i+l-1)%l]);
return 0;
}
通过模运算实现“延申”操作(当然也可以直接延伸)
堆盘子(placement)
#include <stdio.h>
int a[2000][2000];
int x1[9]={0,0,0,1,1,1,-1,-1,-1};
int y1[9]={0,1,-1,0,1,-1,0,1,-1};
void add(int x,int y)
{
for(int i=0;i<9;++i)
++a[x+x1[i]][y+y1[i]];
}
int main(void) {
int n,m,k,ans=0,cnt=1;scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;++i)
{
int x,y;scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
{
if(ans==a[i][j]) ++cnt;
if(ans<a[i][j]) {cnt=1;ans=a[i][j];}
}
printf("%d %d\n",ans,cnt);
return 0;
}
网络迷因
#include <stdio.h>
#include <string.h>
char a[200][200],b[200][200];
char c1[200],c2[200];
char q[200][200];
int n,cnt;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%s%s",a[i],b[i]);
}
scanf("%s%s",c1,c2);
if(strcmp(c1,c2)==0)
{
printf("Yes\n");
return 0;
}
for(int i=1;i<=n;++i)
{
if(strcmp(c1,a[i])==0)
strcpy(q[++cnt],b[i])
,strcpy(a[i],""),strcpy(b[i],"");
if(strcmp(c1,b[i])==0)
strcpy(q[++cnt],a[i])
,strcpy(a[i],""),strcpy(b[i],"");
}
for(int x=1;x<=cnt;++x)
{
if(strcmp(q[x],c2)==0)
{
printf("Yes\n");
return 0;
}
for(int i=1;i<=n;++i)
{
if(strcmp(q[x],a[i])==0)
strcpy(q[++cnt],b[i]),
strcpy(a[i],""),strcpy(b[i],"");
if(strcmp(q[x],b[i])==0)
strcpy(q[++cnt],a[i]),
strcpy(a[i],""),strcpy(b[i],"");
}
}
printf("No\n");
return 0;
}
方法一:定义一个队列,先把c1放进去,然后把与c1等价的都放进去,重复这一过程直到c2入队或者全部入了一遍队为止。注意入队的时候要标记出来避免重复入队。
方法二:并查集+哈希(好复杂,没写)
电话密码
#include <stdio.h>
#include <string.h>
char a[20][20]={"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
char b[20],c[20];
int d[20]={0,0,3,3,3,3,3,4,3,4};
int l,cnt;
void f(int x){
if(x==l){
puts(c);
return;
}
int m=b[x]-'0';
for(int i=0;i<d[m];++i){
c[cnt++]=a[m][i];
f(x+1);
--cnt;
}
}
int main(void) {
gets(b);
l=strlen(b);
f(0);
return 0;
}
递归,每一次找一位数入队并记录方案即可
连续正面的可能性
#include <stdio.h>
int n,m,ans;
int f[200][200][200];
int main(void) {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) f[i][0][0]=f[i][i][i]=1;
for(int i=2;i<=n;++i)
{
for(int j=1;j<i;++j)//unnecessery to check j==1 and j==i
{
for(int k=0;k<=j;++k)
f[i][j][0]+=f[i-1][j][k];
for(int k=1;k<j;++k)
f[i][j][k]+=f[i-1][j][k-1];
f[i][j][j]+=f[i-1][j-1][j-1]+f[i-1][j][j-1];
}
}
for(int k=0;k<=m;++k) ans+=f[n][m][k];
printf("%d\n",ans);
/*
for(int i=0;i<=n;++i)
for(int j=0;j<=i;++j)
for(int k=0;k<=j;++k)
printf("f[%d][%d][%d]=%d\n",i,j,k,f[i][j][k]);
*/
return 0;
}
文心一言似乎有一个\(O(n^2)\)的做法,但是有点瑕疵,我也没能帮他改过来(到底谁是AI
我只想到了这个\(O(n^3)\)的三维dp
设\(f[i][j][k]\)表示i枚硬币最多连续j面朝上且最末尾有k面朝上的方法数
则:
(1) k=0 那前n-1位可以是任意数,\(f[i][j][0]=\Sigma_{k=0}^jf[i-1][j][k]\)
(2) 0<k<j 那么j枚连续朝上的面一定不出现在最后面,所以\(f[i][j][k]=f[i-1][j][k-1]\)
(3) k=j 那么有两种可能:只有最后面j位连续正面是唯一最多的,和前面已经有j位连续正面,最后面又有j位连续正面,所以\(f[i][j][j]=f[i-1][j-1][j-1]+f[i-1][j][j-1]\)
这是合理的状态转移方程!然后跑dp就完事了,最后结果就是\(\Sigma_{k=0}^mf[n][m][k]\)