| 题目 | 难度 | 知识点 |
|---|---|---|
| A 游游的you矩阵 | ★ | 签到/暴力枚举 |
| B 游游的01串操作 | ★ | 枚举/DP |
| C 游游的正整数 | ★★ | 二分 |
| D 游游的选数乘积 | ★★ | 状态计数DP |
打的是一坨,不过确实不太会C和D。确实之前没搞过类似的题目。本套题C是二分应该是可以做出来的但是没做出来,主要没发现那个性质。唉还是太菜了。
游游的you矩阵
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
string s[N];
int n,m,ans;
void solve(int x,int y)
{
map<char,int>mp;
mp[s[x][y]]=1,mp[s[x][y+1]]=1,mp[s[x+1][y]]=1,mp[s[x+1][y+1]]=1;
if(mp['y']&&mp['o']&&mp['u']) ans++;
}
int main(void)
{
cin>>n>>m;
for(int i=0;i<n;i++) cin>>s[i];
for(int i=0;i<n-1;i++)
for(int j=0;j<m-1;j++) solve(i,j);
cout<<ans;
return 0;
}
游游的01串操作
最终状态就两种,枚举求一个min即可。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
string s,temp1,temp2;
LL ans1,ans2;
int main(void)
{
cin>>s;
while(temp1.size()<s.size()) temp1+="01";
while(temp2.size()<s.size()) temp2+="10";
for(int i=0;i<s.size();i++)
{
if(s[i]!=temp1[i]) ans1+=i+1;
if(s[i]!=temp2[i]) ans2+=i+1;
}
cout<<min(ans1,ans2);
return 0;
}
状态机DP搞
#include<bits/stdc++.h>
using namespace std;
const int N=1e5*5+10;
typedef long long int LL;
string s,temp1,temp2;
LL f[N][2];//f[i]前i个字符且最后是[j]的最小花费
int main(void)
{
cin>>s;
if(s[0]=='0') f[0][0]=0,f[0][1]=1;
else f[0][0]=1,f[0][1]=0;
for(int i=1;i<s.size();i++)
{
if(s[i]=='1')
{
f[i][1]=f[i-1][0];
f[i][0]=f[i-1][1]+i+1;
}else{
f[i][0]=f[i-1][1];
f[i][1]=f[i-1][0]+i+1;
}
}
cout<<min(f[s.size()-1][0],f[s.size()-1][1]);
return 0;
}
游游的正整数
令 s = b-a; 题意是若s能落在[0,0][1* l,1* r],[2* l,2* r],[3* l,3* r],.....,[k*l,k *r] (k是非负整数)的某个区间中,就有解,否则无解,只需要两次二分枚举k,一次枚举最大k,一次枚举最小k。
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
LL t,a,b,l,r;
int main(void)
{
cin>>t;
while(t--)
{
cin>>a>>b>>l>>r;
LL temp=b-a;
LL l1=0,r1=1e9;
while(l1<r1)
{
LL mid=(l1+r1)/2;
if(r*mid>=temp) r1=mid;
else l1=mid+1;
}
if(l1*l<=temp&&temp<=l1*r)
{
LL l2=0,r2=1e9;
while(l2<r2)
{
LL mid=(l2+r2+1)/2;
if(l*mid<=temp) l2=mid;
else r2=mid-1;
}
cout<<l1<<" "<<l2<<endl;
}else cout<<-1<<endl;
}
return 0;
}
游游的选数乘积
#include<bits/stdc++.h>
using namespace std;
const int N=100;
typedef long long int LL;
LL cnt[N][N],n,k;
int main(void)
{
cin>>n>>k;
for(int i=0;i<n;i++)
{
int x; cin>>x;
int cnt2=0,cnt5=0;
while(x%2==0) x/=2,cnt2++;
while(x%5==0) x/=5,cnt5++;
cnt[cnt2][cnt5]++;
}
LL ans1=0,ans2=0;
for(int i=0;i<32;i++)//枚举第一种状态
for(int j=0;j<15;j++)
for(int ii=0;ii<32;ii++)//枚举第二种状态
for(int jj=0;jj<15;jj++)
{
if(i+ii<k || j+jj<k) continue;
if(i==ii&&j==jj)//
{
ans1+=cnt[i][j]*(cnt[i][j]-1)/2;
}else
{
ans2+=cnt[i][j]*cnt[ii][jj];
}
}
cout<<ans1+ans2/2;
return 0;
}