A.九进制转十进制(100%)
转10进制,每位按权展开,是后面每一位的权值相乘
#include <iostream>
using namespace std;
int main(){
cout<<1478<<endl;
return 0;
}
B.顺子日期(100%)
方法一:枚举所有日期
#include <iostream>
#include <string>
using namespace std;
signed main(){
int ans=0;
string t1="123",t2="012";
for(int i=1;i<=12;i++){
for(int j=1;j<=31;j++){
string s="2022";
//月份
if(i<=9) s=s+'0'+to_string(i);
else s=s+to_string(i);
//天数
if(j<=9) s=s+'0'+to_string(j);
else s=s+to_string(j);
if(s.find(t1)!=-1||s.find(t2)!=-1){
cout<<s<<endl;
ans++;
}
}
}
cout<<ans<<endl;
return 0;
}
拉excel表格+ctrl+F查找(012、123)
C.刷题统计(100%)
#include <iostream>
#define int long long
using namespace std;
int a[8];
signed main(){
int x1,x2,trg,tot;cin>>x1>>x2>>trg;
tot=5*x1+2*x2;
// cout<<tot<<endl;
for(int i=1;i<=5;i++){
a[i]=x1;
}a[6]=a[7]=x2;
int m=(trg/tot)*7;//1
trg=trg%tot;
if(trg==0){
cout<<m<<endl;
return 0;
}
int i;
for(i=1;i<=7;i++){
trg=trg-a[i];
if(trg<=0) {
break;
}
}
cout<<m+i<<endl;
return 0;
}
D.修建灌木(100%)
找规律
模拟3、4、5可以找到规律
1-----------1
2-----------2
3-----------4
4-----------6
5-----------8
6-----------10
除了第一天都满足2*n-2,从两边向中间递减
#include <iostream>
using namespace std;
const int N=1e4+10;
int n,a[N];
int main(){
std::ios::sync_with_stdio(false);cin.tie(0);
cin>>n;
if(n==1){
cout<<1<<endl;
return 0;
}
int trg=2*n-2;
int l=1,r=n;
while(l<=r){
a[l]=a[r]=trg;
trg=trg-2;
l++;
r--;
}
for(int i=1;i<=n;i++){
cout<<a[i]<<endl;
}
return 0;
}
大模拟
#include <iostream>
#include <string>
#include <vector>
using namespace std;
const int N=1e4+10;
int h[N],ans[N];
int main() {
int n; cin>>n;
//第一次从左往右剪树
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j==i) h[j]=0;
else h[j]++;
ans[j]=max(ans[j],h[j]);
}
}
//调转方向,从右往左剪树
for(int i=n;i>=1;i--){
for(int j=1;j<=n;j++){
if(j==i) h[j]=0;
else h[j]++;
ans[j]=max(ans[j],h[j]);
}
}
//调转方向,从左往右剪树
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j==i) h[j]=0;
else h[j]++;
ans[j]=max(ans[j],h[j]);
}
}
for(int i=1;i<=n;i++) cout<<ans[i]<<endl;
return 0;
}
E.X 进制减法(100%)
#include <iostream>
#include <vector>
#define int long long
using namespace std;
const int N=1e5+10,mod=1e9+7;
int a[N],b[N];
//a 0 4 10 9
//b 0 2 1
//w 2 5 11
//s 1 1*2 1*2*5
signed main(){
int N;cin>>N;
int la;cin>>la;
for(int i=la;i>=1;i--){
cin>>a[i];
}
int lb;cin>>lb;
for(int i=lb;i>=1;i--){
cin>>b[i];
}
int w=2,s=1,ans=0;
for(int i=1;i<=max(la,lb);i++){
w=max((int)2,max(a[i],b[i])+(int)1);
ans=(ans+s*(a[i]-b[i]))%mod;
s=(s*w)%mod;
}
cout<<ans<<endl;
return 0;
}
F.统计子矩阵(70%)
二维前缀和优化 6层变4层
#include <iostream>
#define int long long
using namespace std;
const int N=5e2+10,M=5e2+10;
int a[N][M],n,m,k;
int pre[N][M],ans;
signed main(){
std::ios::sync_with_stdio(false);cin.tie(0);
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
pre[i][j]=pre[i-1][j]+pre[i][j-1]-pre[i-1][j-1]+a[i][j];
}
}
for(int i1=1;i1<=n;i1++){
for(int j1=1;j1<=m;j1++){
for(int i2=i1;i2<=n;i2++){
for(int j2=j1;j2<=m;j2++){
int sum=pre[i2][j2]-pre[i1-1][j2]-pre[i2][j1-1]+pre[i1-1][j1-1];
if(sum<=k) ans++;
}
}
}
}
cout<<ans<<endl;
return 0;
}
G.积木画(false)
可以用递推做 找到前5项,得到递推关系式
#include <iostream>
#include <vector>
#define int long long
using namespace std;
const int N=1e7+10,mod=1e9+7;
int dp[N],n;
signed main(){
cin>>n;
dp[1]=1;dp[2]=2;dp[3]=5;
for(int i=4;i<=n;i++){
dp[i]=(2*dp[i-1]%mod+dp[i-3]%mod)%mod;
}
cout<<dp[n]<<endl;
return 0;
}
H.扫雷(false)
图论算法,连通性问题
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
struct circle { int x, y, r; };
//解法:图的搜索处理图的连通性
//检查圆c是否覆盖点p
bool check(circle c, pii p) {
int t1 = (c.x - p.first) * (c.x - p.first);
int t2 = (c.y - p.second) * (c.y - p.second);
return c.r >= sqrt(t1 + t2);
}
int main() {
int n, m;
cin >> n >> m;
//key:代表坐标x,y,value:代表最大半径和对应数量
map<pii, pii> mp;
//处理炸弹
for (int i = 1; i <= n; i++) {
int x, y, r; cin >> x >> y >> r;
//优化
pii p = { x,y };
mp[p].second++;//统计同一个x,y点炸弹的数量
mp[p].first = max(mp[p].first, r); //统计同一个x,y点炸弹的最大半径
}
//处理火箭弹
queue<circle> q;
for (int i = 1; i <= m; i++) {
int x, y, r; cin >> x >> y >> r;
q.push({ x,y,r });
}
//记录爆炸坐标
set<pii> s;
//记录答案即爆炸数量
int ans = 0;
while (!q.empty()) {
circle cur = q.front(); q.pop();
int x = cur.x, y = cur.y, r = cur.r;
//以i,j为中心,长宽均为2r的正方形范围,这里为了方便直接枚举正方形,后续通过判定排除无效点
for (int i = x - r; i <= x + r; i++) {
for (int j = y - r; j <= y + r; j++) {
pii p = { i,j };
//已经爆炸,不处理
if (s.count(p)) continue;
//该坐标无雷,不处理
if (!mp.count(p)) continue;
//不在范围
if (!check(cur, p)) continue;
s.insert(p);
ans += mp[p].second;
q.push({ i,j,mp[p].first });
}
}
}
cout << ans << endl;
return 0;
}
I.李白打酒加强版(40%)
搜索与回溯
枚举方案数
判断是否需要标记
搜索
回溯
结束条件
#include <iostream>
#include <vector>
#define int long long
using namespace std;
const int mod=1e9+7;
int n,m,ans;
void dfs(int cur_n,int cur_m,int water,string s,int depth){
if(cur_n>n+1||cur_m>m+1||depth>n+m+1) return;
if(cur_n==n+1&&cur_m==m+1&&depth==n+m+1&&water==0&&s.back()=='0'){
ans++;
ans=ans%mod;
// cout<<s<<endl;
return;
}
for(int i=0;i<=1;i++){
//遇花喝一斗前提得有酒
if(i==0&&water>0) dfs(cur_n,cur_m+1,water-1,s+'0',depth+1);
//逢店加一倍
if(i==1) dfs(cur_n+1,cur_m,water*2,s+'1',depth+1);
}
}
signed main(){
cin>>n>>m;
string str;
dfs(1,1,2,str,1);
cout<<ans%mod<<endl;
return 0;
}