因为模拟本来不想写现在觉得还是写一下比较好所以起了这个章节顺序(滑稽保命
模拟就是:题干怎么说,代码怎么写。
模拟是所有题的通用解法,因为按题意解题一点毛病都没有。
就是码量的区别
如果模拟水平不高不建议抱着”大不了写几千行大模拟“的心态写代码。
前面我们提到的”A+B Problem“就是一种模拟。
来看几道例题。
以下题目均来自洛谷
P2669 金币
国王将金币作为工资,发放给忠诚的骑士。第一天,骑士收到一枚金币;之后两天(第二天和第三天),每天收到两枚金币;之后三天(第四、五、六天),每天收到三枚金币;之后四天(第七、八、九、十天),每天收到四枚金币……;这种工资发放模式会一直这样延续下去:当连续 n 天每天收到 n 枚金币后,骑士会在之后的连续 n+1 天里,每天收到 n+1 枚金币。
请计算在前 k 天里,骑士一共获得了多少金币。
输入格式
一个正整数 k,表示发放金币的天数。
输出格式
一个正整数,即骑士收到的金币数。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int main(){
int s,d;
int ans(0);//赋值的另一种写法
cin>>s;
d=s;
//当连续N天每天收到N枚金币后,骑士会在之后的连续N+1天里,每天收到N+1枚金币。
//开始模拟
//天数s=1+2+3+····+x,x可能为0
for(int i=1;i<=d;i++){//枚举天数
if(s>i){
s-=i;//按照时间段计算
ans+=i*i;
}
else {//最后一段时间
ans+=s*i;
break;
}
}
cout<<ans<<endl;
return 0;
}
P1008 三连击
将1,2,…,9 共 9个数分成 3 组,分别组成 3 个三位数,且使这 3 个三位数构成1:2:3 的比例,试求出所有满足条件的 3 个三位数。
输入格式
无
输出格式
若干行,每行3 个数字。按照每行第1 个数字升序排列。
思维难度不是很大但是一位一位弄是真的复杂
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int i,j,l,n,m,x,y,z,d,e,f,g,h,k,v,h[9];
int main() {
for(i=1; i<=3; i++)//最小的数一定不超过333
for(j=1; j<=9; j++)
for(l=1; l<=9; l++) {
x=100*i+10*j+l;
y=x*2;
z=x*3;
/* a=x/100;
b=(x%100)/10;
c=x%10;*/ //可以不要
d=y/100;
e=(y%100)/10;
f=y%10;
g=z/100;
h=(z%100)/10;
k=z%10;
h[0]=i;
h[1]=j;
h[2]=l;
h[3]=d;
h[4]=e;
h[5]=f;
h[6]=g;
h[7]=h;
h[8]=k;
for(m=0; m<=7; m++)//枚举最后的两个数字
for(n=m+1; n<=8; n++) {
if(h[m]==h[n]||h[m]==0||h[n]==0)
//if(h[m]!=h[n]){if(e!=0&&f!=0&&h!=0&&k!=0&&z<999) 不可,否则循环只走一遍就会往下判断,出现数字重复
v=1;//标记变量,防止出现0、相等的数
}
if(v!=1&&z<=999)//*2,*3后y,z的十位和个位上都有可能出现0;不能连续相等或不等;控制z<1000
cout<<x<<" "<<y<<" "<<z<<endl;
v=0;//标记最好定义成局部变量,用完要清零。也可以放在h[8]=k之后
}
return 0;
}
- P2615 神奇的幻方
神奇的幻方
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cctype>
#define maxn 50
#define MAXN 2000
using namespace std;
int n,lin[MAXN],col[MAXN],table[maxn][maxn];
inline int read(int &x){//快读,这个版本不能用于负数。这个“输入”可以加快程序读入的速度。不是必须的。
char c=0;
x=0;
while(!isdigit(c))
c=getchar();
while(isdigit(c))
x=x*10+c-'0',c=getchar();
}
inline int write(int x){//快写,不是必须的
if(x<0)
putchar('-'),x=-x;
if(x>9)
write(x/10);
putchar(x%10+'0');
}
int main(){
read(n);
//先填1
table[1][n/2+1]=1;//table记录某行某列有没有数字
lin[1]=1;//lin[i]记录数字i填在第几行
col[1]=n/2+1;//col[i]记录数字i填在第几列
for(int k=2;k<=n*n;k++){//从2开始分情况判断并填写
if(lin[k-1]==1&&col[k-1]!=n){
//若 (K−1)在第一行但不在最后一列,则将 K填在最后一行, (K−1) 所在列的右一列
//下面偷懒不写了(逃
table[n][col[k-1]+1]=k;
lin[k]=n;
col[k]=col[k-1]+1;
}
else if(lin[k-1]!=1&&col[k-1]==n){
table[lin[k-1]-1][1]=k;
lin[k]=lin[k-1]-1;
col[k]=1;
}
else if(lin[k-1]==1&&col[k-1]==n){
table[2][n]=k;
lin[k]=2;
col[k]=n;
}
else if(lin[k-1]!=1&&col[k-1]!=n){
if(table[lin[k-1]-1][col[k-1]+1]==0){
table[lin[k-1]-1][col[k-1]+1]=k;
lin[k]=lin[k-1]-1;
col[k]=col[k-1]+1;
}
else{
table[lin[k-1]+1][col[k-1]]=k;
lin[k]=lin[k-1]+1;
col[k]=col[k-1];
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
write(table[i][j]);
putchar(' ');
}
printf("\n");
}
return 0;
}
就酱