人要有自信,人有了自信才会拥有一切
C
分析:仔细观察我们可以发现所谓第k位的规律
第1位 00
第2位 02
第3位 04
第6位 20
第7位 22
第8位 24
这是5个为一个周期的循环
当然周期的下标是从0开始的,所以我们可以在刚开始把 k--
用一个数组记录一下周期
#include <iostream>
#include <cstring>
#include <algorithm>
#
using namespace std;
#define int long long
char a[]={'0','2','4','6','8'};
signed main(){
int n;
cin>>n;
string ans=""; n--;
if(!n){
cout<<0<<endl;
return 0;
}
while(n){
int now=n%5;
ans+=a[now];
// cout<<a[now];
n/=5;
}
reverse(ans.begin(),ans.end());
cout<<ans<<endl;
}
D
dp
环境很重要,你周围的环境(周围的环境只支持你到达这一高度)和你自己的高度(如果自己不努力那么环境再好也没用)取一个最小值
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1000010;
int a[N],pre[N],suf[N];
void solve(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
pre[i]=min(pre[i-1]+1,a[i]);
}
int ans=1;
for(int i=n;i>=1;i--){
suf[i]=min(suf[i+1]+1,a[i]);
ans=max(ans,min(pre[i],suf[i]));
}
cout<<ans<<endl;
}
signed main(){
int t=1;
while(t--){
solve();
}
}
E
数位dp
分析:数据最高是1e14,那么可能的数位之和只有1-9*14,将每一种可能的数位之和dp,求出答案
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define int long long
const int N = 1000010;
int a[N],pre[N],suf[N];
int dp[50][10*20][10*20];
int m;
int dfs(int cnt,int sum,int mod,int limit){
if(sum>m) return 0;
if(!cnt) return sum==m && mod==0;
if(!limit && dp[cnt][sum][mod]!=-1 ) return dp[cnt][sum][mod];
int ans=0;
int e;
if(limit)e=a[cnt];
else e=9;
for(int i=0;i<=e;i++){
ans+=dfs(cnt-1,sum+i,(mod*10+i)%m,limit && i==a[cnt]);
}
if(!limit) dp[cnt][sum][mod]=ans;
return ans;
}
void solve(){
int n;
cin>>n;
int cnt=0;
while(n){
a[++cnt]=n%10;
n/=10;
}
int ans=0;
for(int i=1;i<=cnt*9;i++){
m=i;
memset(dp,-1,sizeof dp);
ans+=dfs(cnt,0,0,1);
}
cout<<ans;
}
signed main(){
int t=1;
//cin>>t;
while(t--){
solve();
}
}
F
双向搜索
丑陋的实现:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <queue>
#include<array>
#include<unordered_map>
using namespace std;
#define int long long
const int N = 1000010;
int n,m;
unordered_map<string,int>mp1,mp2;
int get(int x,int y){
return (x-1)*m+y;
}
void bfs(string tt,int mapid){
queue<string>q;
q.push(tt);
if(mapid==1)mp1[tt]=0;
else mp2[tt]=0;
while(q.size()){
auto t=q.front();
q.pop();
if(mapid==1 && mp1[t]>=10) break;
else if(mapid==2 && mp2[t]>=10) break;
for(int i=0;i<=1;i++){
for(int j=0;j<=1;j++){//循环改变的位置
string tmp=t;
for(int a=1;a<n;a++){
for(int b=1;b<m;b++){
tmp[get(i+a,j+b)]=t[get(n-a+i,m-b+j)];
}
}
if(mapid==1 && !mp1.count(tmp) ){
mp1[tmp]=mp1[t]+1;
q.push(tmp);
}
if(mapid==2 && !mp2.count(tmp) ){
mp2[tmp]=mp2[t]+1;
q.push(tmp);
}
}
}
}
}
void solve(){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
cin>>n>>m;
int now=1;
string start=" ";
string ed=" ";
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int x;
cin>>x;
start+=(char)(x+'0');
ed+=(char)(now+'0');
now++;
}
}
//cout<<start<< " "<<ed<<"\n";
bfs(start,1);
bfs(ed,2);
int ans=1e18;
for(auto c:mp1){
//cout<<c.first<<endl;
if(mp2.count(c.first)){
ans=min(ans,mp1[c.first]+mp2[c.first]);
}
}
if(ans==1e18)cout<<-1<<'\n';
else cout<<ans<<'\n';
}
signed main(){
int t=1;
//cin>>t;
while(t--){
solve();
}
}