1 九进制转十进制
手算2*9^3+2*9^1+2*9^0
答案:1478
2 顺子日期
个人提交的是认为012也算,交了答案14
附上代码
#include<bits/stdc++.h>
using namespace std;
int m[15]={0,31,28,31,30,31,30,31,31,30,31,30,31};//月份的基本写法
int main()
{
//分析过2022,不可能出现202234这种,所有可以直接枚举这一年的月份即可
int ans=0;
for(int i=1;i<=12;i++)
for(int j=1;j<=m[i];j++)
{
int a1=i/10,a2=i%10,a3=j/10,a4=j%10;
if(a1+1==a2&&a2+1==a3||a2+1==a3&&a3+1==a4) ans++;
}
cout<<ans<<endl;
return 0;
}
3 刷题统计
这题很简单直接算有多少周和剩下有多少天加起来即可
代码附上
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;//数据过大得开ll
int main()
{
ll a,b,n;
cin>>a>>b>>n;
ll w=n/(5*a+2*b),m=n%(5*a+2*b);//w是多少个星期,m是剩下的多少天
if(m>5*a+b) cout<<7*w+7;//假如剩下的天数大于6天的话,则需要加上7天
else if(m>5*a) cout<<7*w+6;//假如剩下的天数大于5天的话,则需要加上6天
else{
if(m%a) cout<<7*w+m/a+1;//假如m/a还有剩,也就是m%a!=0,则得加多m/a+1天
else cout<<7*w+m/a;//否则没有剩,直接加上m/a天
}
return 0;
}
4 修剪灌木
这题一分析就可以分析出来,要么左边最大要么右边最大
附上代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
cout<<2*max(i-1,n-i)<<endl;//输出左右两边最大
return 0;
}
5 X 进制减法
考试的时候没想明白进制怎么转换的,最后才知道是当前数乘以前几位的进制
如题目的321转为65:3*10*2+2*2+1=65;
这题根据示例盲猜进制为两个位数的最大数+1,但实际上确实这样,至于证明过程就不证了
附上我的代码
#include <iostream>
using namespace std;
typedef long long ll;
const int N=1e5+10,mod=1000000007;
int a[N],b[N];
ll c[N]={1,1};
int main()
{
ll n,ans=0;
cin>>n;
ll ma,mb;
cin>>ma;
for(ll i=ma;i>=1;i--) cin>>a[i];
cin>>mb;
for(ll i=mb;i>=1;i--) cin>>b[i];
for(ll i=1;i<=ma;i++) c[i]=(c[i-1]*(max(2,max(a[i],b[i])+1)))%mod;//处理没一位要乘以的数,也就是前i-位的进制积
for(ll i=ma;i>=1;i--) ans+=(ll)((a[i]-b[i])*c[i-1])%mod;//每一位乘以对应的进制
cout<<(ans%mod+mod)%mod;//由于答案可能mod出负数,这样就保证mod出是正数
return 0;
}
6 统计子矩阵
考试时交了二维矩阵和的做法,时间复杂度O(n^4),只能过70%的数据
后来才知道把二维优化成一维前缀和,再加上双指针,时间复杂度O(n^3),直接AC
附上AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=510;
ll s[N][N];//定义一个求二维数组的一维前缀和,就是第j列的前缀和
int main()
{
ll n,m,k,ans=0;
cin>>n>>m>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>s[i][j],s[i][j]+=s[i-1][j];
//把上下边界中的数看成一维数组
for(int i=1;i<=n;i++)//枚举上边界
for(int j=i;j<=n;j++)//枚举下边界
for(int l=1,r=1,sum=0;r<=m;r++)//双指针分别指向上下边界中的一维数组
{
sum+=s[j][r]-s[i-1][r];//算一下该列的和
while(sum>k)//假如前缀和大了,则缩小左边界
{
sum-=s[j][l]-s[i-1][l];
l++;
}
ans+=r-l+1;//相当于一维求子矩阵的数
}
cout<<ans;
return 0;
}
7 积木画
来看看线性DP
附上代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10,mod=1e9+7;
long long f[N][3];//f[i][j]表示第i-1列填满,第i列的状态是j的方案数
/*
f[i][0]表示i-1列填满,第i列的上面填了
f[i][1]表示i-1列填满,第i列的下面填了
f[i][2]表示i-1列填满,第i列全填
*/
int main()
{
int n;
cin>>n;
f[0][2]=1;//初始化为1
for(int i=1;i<=n;i++)
{
//f[i-1][1]+上面放一条横的+f[i-2][2]+放一个倒L的方块
f[i][0]=(f[i-1][1]+f[i-2][2])%mod;
//f[i-1][0]+下面放一条横的+f[i-2][2]+放一个L的方块
f[i][1]=(f[i-1][0]+f[i-2][2])%mod;
// f[i-1][2]+放一条竖的长条 + f[i-2][2]+放两个横着的长条 + f[i-1][0]+J一样的方块 + f[i-1][1]+7一样的方块
f[i][2]=(f[i-1][2]+f[i-2][2]+f[i-1][0]+f[i-1][1])%mod;
}
cout<<f[n][2]%mod;//输出第n横全放满的方案数
}
8 扫雷
暂时还不会
QAQ,先跳过
9 : 李白打酒加强版
很典型的DP,但是我就是没想到,差一步就弄出来了QAQ
下面来看代码
#include<bits/stdc++.h>
using namespace std;
const int N=110,mod=1e9+7;
int f[N][N][N];//表示遇到i家店,j朵花,壶里酒有k斗的方案数
int main()
{
int n,m;
cin>>n>>m;
f[0][0][2]=1;//初始化刚开始遇到0家店,0朵花,壶里酒有2斗的方案数
for(int i=0;i<=n;i++)//枚举店
for(int j=0;j<=m;j++)//枚举花
for(int k=0;k<=m;k++)//枚举酒
{
int &v=f[i][j][k];//让v直接等价于f[i][j][k],能直接改变值
if(i&&k%2==0) v=(v+f[i-1][j][k/2])%mod;//因为要从i-1与k/2转移,则要保证i>=1&&k%2==0
if(j) v=(v+f[i][j-1][k+1])%mod;//因为要从j-1转移,则要保证j>=1
}
cout<<f[n][m-1][1]%mod;//因为题目说最后一次遇到花,则输出前一步
}
10 砍竹子
考试时以为全部相同的高度就全部变,谁知道是相邻的高度相同才能一起变,直接哭死
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
vector<unordered_set<ll>> ha;
ll s(ll x)//用来更新结果
{
return sqrt(x/2+1);
}
int main()
{
ll n,ans=0;
cin>>n;
ha.resize(2);//分配空间,用滚动数组优化
for(int i=1;i<=n;i++)//将n个数分解成最多6个数
{
ll x;
cin>>x;
while(x>1)//将x进行分解
{
if(!ha[i&1].count(x)) ans++;//假如不连续,也就是上一个数的set没有出现过这个数,则答案加1
ha[i-1&1].insert(x);//把这个数放进另一列中
x=s(x);//分解这个数
}
ha[i&1].clear();//把比较完的数清空,没用了
}
cout<<ans;
return 0;
}