一、九进制转十进制
#include<bits/stdc++.h>
using namespace std;
int main()
{
printf("%d",2*1+2*9+0*9*9+2*9*9*9);
return 0;
}
二、顺子日期
简单的日期判断
#include<bits/stdc++.h>
using namespace std;
int d1[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int cnt;
bool check(int a,int b,int c,int d)
{
int mon=a*10+b;
int day=c*10+d;
for(int i=1;i<=12;i++)
if(mon==i&&day>0&&day<=d1[i])
return true;
return false;
}
bool check1(int a,int b,int c,int d)
{
if(a+1==b&&b+1==c)
return true;
if(b+1==c&&c+1==d)
return true;
return false;
}
int main()
{
for(int i=0;i<=9;i++)
for(int j=0;j<=9;j++)
for(int k=0;k<=9;k++)
for(int o=0;o<=9;o++)
if(check(i,j,k,o)&&check1(i,j,k,o))
cnt++;
printf("%d",cnt);
return 0;
}
三、刷题统计
粗心了,注意即使通过了样例也要检查一遍代码逻辑
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int main()
{
LL a,b,n;
scanf("%lld%lld%lld",&a,&b,&n);
LL ans=0;
//每周可以完成的题量
LL week=5*a+2*b;
ans+=(n/week*7);
//剩下需要完成的题
LL s=n%week;
if(s==0)
{
printf("%lld",ans);
return 0;
}
for(LL i=1;i<=7;i++)
{
if(i==6||i==7)
s-=b;
else
s-=a;
if(s<=0)
{
printf("%lld",ans+i);
break;
}
}
return 0;
}
四、修剪灌木
可以模拟也可以找规律推公式
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
printf("%d\n",2*max(i-1,n-i));
return 0;
}
五、X进制减法
没看懂题目
六、统计子矩阵
优化版本还没学会
二维前缀和,公式不是很熟
输入时:s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j]
求区间和(左上角(x1,y1),右下角(x2,y2)):sum=s[x2][y2]-s[x1-1][y2]-s[x2][y1-1]+s[x1-1][y1-1]
1、暴力+二维前缀和
过一半超时
#include<bits/stdc++.h>
using namespace std;
const int N=510;
int n,m,k;
int g[N][N];
int s[N][N];//前缀和
long long cnt=0;
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&g[i][j]);
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+g[i][j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int x=i;x<=n;x++)
for(int y=j;y<=m;y++)
{
int sum=s[x][y]-s[i-1][y]-s[x][j-1]+s[i-1][j-1];
if(sum<=k)
cnt++;
}
printf("%lld",cnt);
return 0;
}
七、积木画
状态压缩dp
#include<bits/stdc++.h>
using namespace std;
const int N=10000010,MOD=1000000007;
int dp[N][4];
//dp[i][j]表示第i-1列已经放好时,第i列的状态为j
//属性:数量
//放第i列
//j=00,i+1列有00、01、10、11
//j=01,i+1列有10、11
//j=10,i+1列有01、11
//j=11,i+1列有00
int g[4][4]=
{{1,1,1,1},
{0,0,1,1},
{0,1,0,1},
{1,0,0,0}};
int main()
{
int n;
scanf("%d",&n);
//初始化
dp[1][0]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
dp[i+1][k]=(dp[i+1][k]+dp[i][j]*g[j][k])%MOD;
printf("%d",dp[n+1][0]);
return 0;
}
九、李白打酒加强版
i,j的初始值要从定义出发,不能只看初始化
要时刻想到当前是最后一步,如果最后一步是店/花,所以经过店/花的数量至少都是1
#include<bits/stdc++.h>
using namespace std;
const int N=110,MOD=1000000007;
int dp[N][N][N];
//dp[i][j][c]表示遇到i次店,j次花还剩c斗酒的方案
//属性:数量
//1、最后一步遇到店,需要满足i>=1和c%2==0,dp[i+1][j][c]+=dp[i][j][c/2]
//2、最后一步遇到花,需要满足j>=1,dp[i][j+1][c]+=dp[i][j][c+1]
int main()
{
int n,m;
scanf("%d%d",&n,&m);
//初始化
dp[0][0][2]=1;
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
for(int k=0;k<=m;k++)// 最多就是花的数量,如果大于这个数,就肯定喝不完
{
if(i>=1&&k%2==0)
dp[i][j][k]=(dp[i-1][j][k/2]+dp[i][j][k])%MOD;
if(j>=1)
dp[i][j][k]=(dp[i][j-1][k+1]+dp[i][j][k])%MOD;
}
printf("%d",dp[n][m-1][1]);
return 0;
}