(今天刚补完G,感觉不错的一场)。
分析
语法题,判断即可
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define lowbit(x) x&(-x)
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
#define two(x) __builtin_popcount(x)
using namespace std;
typedef pair<ll,ll> PII;
const int mod=998244353;
ll qmi(ll a,ll b){ll res=1ll;while(b){if(b&1) res=res*a;b>>=1;a=(a)*(a);}return res;}
//ll qmi(ll a,ll b,ll mod){ll res=1ll;while(b){if(b&1) res=(res%mod)*a%mod;b>>=1;a=(a%mod)*(a%mod)%mod;}return res%mod;}
//const int N=2001020;
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} //最大公约数
//ll fact[N],infact[N];
//void c(ll mod){fact[0]=infact[0]=1;for(ll i=1;i<=N-5;i++){fact[i]=(i%mod*fact[i-1]%mod)%mod;infact[i]=(infact[i-1]%mod)*(qmi(i,mod-2,mod)%mod)%mod;}}
//ll C(ll a,ll b,ll mod){return ((fact[a]%mod*infact[b]%mod)%mod*(infact[a-b]%mod)%mod)%mod;}//组合数
//void creat(int x){heap[++cnt]=x;int t=cnt;while(t>1 && heap[t]<heap[t/2]){swap(heap[t/2],heap[t]);t/=2;}heap[t]=x;}
void solve(){
int a,b,c;
cin>>a>>b>>c;
if(a<b && b<c) cout<<"STAIR\n";
else if(a<b && c<b) cout<<"PEAK\n";
else cout<<"NONE\n";
}
int main(){
IOS
int t;
t=1;
cin>>t;
while(t--) solve();
return 0;
}
很容易发现一个规律,就是关于行列模4的一个规律(具体见代码)。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define lowbit(x) x&(-x)
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
#define two(x) __builtin_popcount(x)
using namespace std;
typedef pair<ll,ll> PII;
const int mod=998244353;
ll qmi(ll a,ll b){ll res=1ll;while(b){if(b&1) res=res*a;b>>=1;a=(a)*(a);}return res;}
//ll qmi(ll a,ll b,ll mod){ll res=1ll;while(b){if(b&1) res=(res%mod)*a%mod;b>>=1;a=(a%mod)*(a%mod)%mod;}return res%mod;}
//const int N=2001020;
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} //最大公约数
//ll fact[N],infact[N];
//void c(ll mod){fact[0]=infact[0]=1;for(ll i=1;i<=N-5;i++){fact[i]=(i%mod*fact[i-1]%mod)%mod;infact[i]=(infact[i-1]%mod)*(qmi(i,mod-2,mod)%mod)%mod;}}
//ll C(ll a,ll b,ll mod){return ((fact[a]%mod*infact[b]%mod)%mod*(infact[a-b]%mod)%mod)%mod;}//组合数
//void creat(int x){heap[++cnt]=x;int t=cnt;while(t>1 && heap[t]<heap[t/2]){swap(heap[t/2],heap[t]);t/=2;}heap[t]=x;}
void solve(){
int a,b,c;
cin>>a>>b>>c;
if(a<b && b<c) cout<<"STAIR\n";
else if(a<b && c<b) cout<<"PEAK\n";
else cout<<"NONE\n";
}
int main(){
IOS
int t;
t=1;
cin>>t;
while(t--) solve();
return 0;
}
其实就是个考察读入数字和字符分开的知识点。注意特判以下,然后就结束了。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define lowbit(x) x&(-x)
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
#define two(x) __builtin_popcount(x)
using namespace std;
typedef pair<ll,ll> PII;
const int mod=998244353;
ll qmi(ll a,ll b){ll res=1ll;while(b){if(b&1) res=res*a;b>>=1;a=(a)*(a);}return res;}
//ll qmi(ll a,ll b,ll mod){ll res=1ll;while(b){if(b&1) res=(res%mod)*a%mod;b>>=1;a=(a%mod)*(a%mod)%mod;}return res%mod;}
//const int N=2001020;
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} //最大公约数
//ll fact[N],infact[N];
//void c(ll mod){fact[0]=infact[0]=1;for(ll i=1;i<=N-5;i++){fact[i]=(i%mod*fact[i-1]%mod)%mod;infact[i]=(infact[i-1]%mod)*(qmi(i,mod-2,mod)%mod)%mod;}}
//ll C(ll a,ll b,ll mod){return ((fact[a]%mod*infact[b]%mod)%mod*(infact[a-b]%mod)%mod)%mod;}//组合数
//void creat(int x){heap[++cnt]=x;int t=cnt;while(t>1 && heap[t]<heap[t/2]){swap(heap[t/2],heap[t]);t/=2;}heap[t]=x;}
void solve(){
int h,m;
scanf("%02d:%02d",&h,&m);
if(h==0){
printf("%02d:%02d AM\n",h+12,m);
}else{
if(h<12){
printf("%02d:%02d AM\n",h,m);
}else if(h==12){
printf("%02d:%02d PM\n",h,m);
}else printf("%02d:%02d PM\n",h-12,m);
}
}
int main(){
//IOS
int t;
t=1;
cin>>t;
while(t--) solve();
return 0;
}
挺有含金量,我们不妨考虑,从小往大去枚举所有满足二进制的约数,然后一一除去,再看剩下的这个数是不是也满足二进制的规律,满足的话就结束,否则全试除完了,要是还是不满足,就输出。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define lowbit(x) x&(-x)
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
#define two(x) __builtin_popcount(x)
using namespace std;
typedef pair<ll,ll> PII;
const int mod=998244353;
ll qmi(ll a,ll b){ll res=1ll;while(b){if(b&1) res=res*a;b>>=1;a=(a)*(a);}return res;}
//ll qmi(ll a,ll b,ll mod){ll res=1ll;while(b){if(b&1) res=(res%mod)*a%mod;b>>=1;a=(a%mod)*(a%mod)%mod;}return res%mod;}
//const int N=2001020;
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} //最大公约数
//ll fact[N],infact[N];
//void c(ll mod){fact[0]=infact[0]=1;for(ll i=1;i<=N-5;i++){fact[i]=(i%mod*fact[i-1]%mod)%mod;infact[i]=(infact[i-1]%mod)*(qmi(i,mod-2,mod)%mod)%mod;}}
//ll C(ll a,ll b,ll mod){return ((fact[a]%mod*infact[b]%mod)%mod*(infact[a-b]%mod)%mod)%mod;}//组合数
//void creat(int x){heap[++cnt]=x;int t=cnt;while(t>1 && heap[t]<heap[t/2]){swap(heap[t/2],heap[t]);t/=2;}heap[t]=x;}
bool check(int x){
string s=to_string(x);
int ans1=0;
for(int i=0;i<s.size();i++){
if(s[i]=='0' || s[i]=='1') ans1++;
}
return ans1==(int)s.size();
}
void solve(){
int n;
cin>>n;
int t=n;
if(check(t)){
cout<<"YES\n";
return;
}
for(int i=2;i<=n/i;i++){
if(t<i) break;
if(check(i)){
if(t%i==0){
while(t%i==0){
t/=i;
if(check(t)){
cout<<"YES\n";
return;
}
}
}
}
}
// cout<<t<<"\n";
if(check(t)) cout<<"YES\n";
else cout<<"NO\n";
}
int main(){
IOS
int t;
t=1;
cin>>t;
while(t--) solve();
return 0;
}
我麻了,开始搞什么魔幻二分做法,然后,其实这题就是纯暴力题,里面加个小的优化就是我们找长度为l的最多出现的串用即可。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define lowbit(x) x&(-x)
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
#define two(x) __builtin_popcount(x)
using namespace std;
typedef pair<ll,ll> PII;
const int mod=998244353;
ll qmi(ll a,ll b){ll res=1ll;while(b){if(b&1) res=res*a;b>>=1;a=(a)*(a);}return res;}
//ll qmi(ll a,ll b,ll mod){ll res=1ll;while(b){if(b&1) res=(res%mod)*a%mod;b>>=1;a=(a%mod)*(a%mod)%mod;}return res%mod;}
//const int N=2001020;
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} //最大公约数
//ll fact[N],infact[N];
//void c(ll mod){fact[0]=infact[0]=1;for(ll i=1;i<=N-5;i++){fact[i]=(i%mod*fact[i-1]%mod)%mod;infact[i]=(infact[i-1]%mod)*(qmi(i,mod-2,mod)%mod)%mod;}}
//ll C(ll a,ll b,ll mod){return ((fact[a]%mod*infact[b]%mod)%mod*(infact[a-b]%mod)%mod)%mod;}//组合数
//void creat(int x){heap[++cnt]=x;int t=cnt;while(t>1 && heap[t]<heap[t/2]){swap(heap[t/2],heap[t]);t/=2;}heap[t]=x;}
int n;
const int N=500010;
int primes[N];
bool st[N]={false};
int cnt=0;
map<string,int> mp;
void solve(){
cin>>n;
string s;
cin>>s;
//if(!st[n]) cout<<n<<"\n";
//else{
vector<int> v;
for(int i=1;i<=n;i++){
if(n%i==0){
v.push_back(i);
}
}
//v.push_back(n);
//int l=0,r=v.size()-1;
for(int i=0;i<v.size();i++){
int mid=i;
int m=0;
mp.clear();
while(m!=s.size()){
string t=s.substr(m,v[mid]);
mp[t]++;
m+=v[mid];
}
int maxn=0;
for(auto it:mp){
maxn=max(maxn,it.y);
}
string te;
for(auto it:mp){
if(it.y==maxn){
te=it.x;
break;
}
}
int ans=0;
m=0;
while(m!=(int)s.size()){
for(int i=m;i<m+te.size();i++){
if(te[i-m]!=s[i]) ans++;
}
m+=(int)te.size();
}
if(ans<=1){
cout<<v[i]<<"\n";
break;
}
}
// }
}
int main(){
IOS
int t;
t=1;
cin>>t;
// prime(N-10);
while(t--) solve();
return 0;
}
是个很有意思的数学题,使用二叉树的性质,我们肯定是先考虑有两个儿子的节点,把这些层数都确定完了,我们再去考虑一个儿子的,那么我们可以想一下,假如深度是,假设第层还剩个位置没有放两个儿子的节点,那么肯定是先填满这个节点,如果不够就往下加就行了,如果够,那我们的深度就没必要加了,这个也好算,就是总的节点第层的节点数-(总节点数-前层总和),即 ),至于的情况就很好判断了。因为无论怎么增加,我们最后一层两个儿子节点数和一个儿子节点数之和是不变的。所以这个必须与个儿子的节点数相同,否则就输出。
(感觉说的很清楚了)。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define lowbit(x) x&(-x)
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
#define two(x) __builtin_popcount(x)
using namespace std;
typedef pair<ll,ll> PII;
const int mod=998244353;
ll qmi(ll a,ll b){ll res=1ll;while(b){if(b&1) res=res*a;b>>=1;a=(a)*(a);}return res;}
//ll qmi(ll a,ll b,ll mod){ll res=1ll;while(b){if(b&1) res=(res%mod)*a%mod;b>>=1;a=(a%mod)*(a%mod)%mod;}return res%mod;}
//const int N=2001020;
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} //最大公约数
//ll fact[N],infact[N];
//void c(ll mod){fact[0]=infact[0]=1;for(ll i=1;i<=N-5;i++){fact[i]=(i%mod*fact[i-1]%mod)%mod;infact[i]=(infact[i-1]%mod)*(qmi(i,mod-2,mod)%mod)%mod;}}
//ll C(ll a,ll b,ll mod){return ((fact[a]%mod*infact[b]%mod)%mod*(infact[a-b]%mod)%mod)%mod;}//组合数
//void creat(int x){heap[++cnt]=x;int t=cnt;while(t>1 && heap[t]<heap[t/2]){swap(heap[t/2],heap[t]);t/=2;}heap[t]=x;}
int n;
const int N=500010;
int primes[N];
bool st[N]={false};
int cnt=0;
map<string,int> mp;
void solve(){
int a,b,c;
cin>>a>>b>>c;
int i=1;
while(qmi(2,i)-1<a){
i++;
}
if(a==0){
i=0;
}
//cout<<i<<"\n";
int depth=i;
int up=qmi(2,i)-1-a;
//cout<<up<<" ";
int down=0;
if(i!=0){
down=2*qmi(2,i-1)-2*up;
}else down=1;
if(b<=up){
//up-=b;
if(up+down!=c){
cout<<"-1\n";
}else cout<<depth<<"\n";
}else{
b-=up;
int add=0;
if(b%(up+down)==0) depth+=b/(up+down);
else depth+=b/(up+down)+1;
if(up+down!=c){
cout<<"-1\n";
}else cout<<depth<<"\n";
}
}
int main(){
IOS
int t;
t=1;
cin>>t;
// prime(N-10);
while(t--) solve();
return 0;
}
赛时没来得及看,(卡死我了草)。后来看了下,是一个相当相当有意思的状压。很适合新手做题,我也是听佬讲了一半会了,感觉这些基础的状压都是一个套路,考虑,表示一个二进制串,就是表示取哪些数和表示不取哪些数。是表示最后一次操作我们取的是哪个数。然后写写写然后,后来发现哦,要优化,要把对每个串符合要求的都存进里面,对不起,然后过了,具体转移方程见代码,很清晰。
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define ll long long
#define lowbit(x) x&(-x)
#define x first
#define y second
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
#define two(x) __builtin_popcount(x)
using namespace std;
typedef pair<ll,ll> PII;
const int mod=998244353;
ll qmi(ll a,ll b){ll res=1ll;while(b){if(b&1) res=res*a;b>>=1;a=(a)*(a);}return res;}
//ll qmi(ll a,ll b,ll mod){ll res=1ll;while(b){if(b&1) res=(res%mod)*a%mod;b>>=1;a=(a%mod)*(a%mod)%mod;}return res%mod;}
//const int N=2001020;
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;} //最大公约数
//ll fact[N],infact[N];
//void c(ll mod){fact[0]=infact[0]=1;for(ll i=1;i<=N-5;i++){fact[i]=(i%mod*fact[i-1]%mod)%mod;infact[i]=(infact[i-1]%mod)*(qmi(i,mod-2,mod)%mod)%mod;}}
//ll C(ll a,ll b,ll mod){return ((fact[a]%mod*infact[b]%mod)%mod*(infact[a-b]%mod)%mod)%mod;}//组合数
//void creat(int x){heap[++cnt]=x;int t=cnt;while(t>1 && heap[t]<heap[t/2]){swap(heap[t/2],heap[t]);t/=2;}heap[t]=x;}
const int N=16;
bool dp[1<<N][N]={false};
struct mes{
string a,b;
}name[N];
int n;
int cnt[1<<N];
vector<int> v[N];
void solve(){
cin>>n;
vector<int> v[N];
for(int i=0;i<(1<<n);i++){
for(int j=0;j<n;j++){
dp[i][j]=false;
}
}
for(int i=0;i<n;i++){
dp[1<<i][i]=true;
}
for(int i=0;i<n;i++){
cin>>name[i].a>>name[i].b;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(j!=i && (name[j].a==name[i].a || name[j].b==name[i].b)){
v[i].push_back(j);
v[j].push_back(i);
}
}
}
for(int i=1;i<(1<<n);i++){
for(int j=0;j<n;j++){
if((i>>j&1)){
for(int k=0;k<v[j].size();k++){
if((i-(1<<j))>>v[j][k]&1){
dp[i][j]|=dp[i-(1<<j)][v[j][k]];
}
}
}
}
}
int res=0;
int ans=0;
for(int i=0;i<(1<<n);i++){
for(int j=0;j<n;j++){
if(dp[i][j]){
ans++;
res=max(cnt[i],res);
}
}
}
cout<<n-res<<"\n";
}
int main(){
IOS
//cout<<("-5"<"-6");
int t;
t=1;
cin>>t;
for(int i=0;i<(1<<N);i++){
cnt[i]=two(i);
}
//scanf("%d",&t);
while(t--) solve();
return 0;
}