1,cf Tokitsukaze and Good 01-String (easy version);2, Tokitsukaze and Good 01-String (hard version);4,acwing 1106.山峰和山谷;5,Air Cownditioning B及一些例题;6,bfs保存最短路径;
1,Tokitsukaze and Good 01-String (easy version)
题意:给长度为偶数的字符串,仅包含0和1,称一个字符串是好的:当所有的1子串和0子串长度也为偶数时称为好的,否则你可以操作:将0变成1或将1变成0,使其变为好的,输出最小的操作次数;
思路:每两个每两个的看,即看二元组;如果相邻的下一位不同,则需要修改;
这样二元组看的好处就是可以使得最少的次数使其0子串和1子串变成偶数长度;
可以拿”1110011100“多举几个例子,变式,”1100011100“等,就发现这样看的好处了;
#include
#pragma GCC optimize(2)
#define rep1(i,a,n) for(ll i=a;ia;i--)
#define per2(i,n,a) for(ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pb push_back
#define endl "\n"
#define lowbit(m) (-m&m)
#define yes cout<<"YES\n"
#define no cout<<"NO\n"
#define yi first
#define er second
using namespace std;
typedef long long ll;
typedef pair PII;
typedef double db;
int n;
string s;
void solve()
{
cin>>n;
cin>>s;
int ans=0;
for(int i=0;i=n)break;
if(s[i+1]!=s[i])ans++;
}
cout<>T;
while(T--)solve();
return 0;
}
2,hard version
题意:除了输出最小操作次数,还需要保证分成的连续0子串和1子串数目最小;
eg:1110011000,最小操作次数是3,最少数目是2;即:1100000000或者,111100000;
但是这种修改很难短时间想到s[i+1]改还是s[i]改,改成0还是1;
所以一种思想是,直接贪心认为它改到了最优的结果,然后遍历时,多看一下s[i]==s[i+1]的情况,
进而看s[i]和前边的队伍关系,不同则长度加1;
最后特判下长度,最少是1;
#include
#pragma GCC optimize(2)
#define rep1(i,a,n) for(ll i=a;ia;i--)
#define per2(i,n,a) for(ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pb push_back
#define endl "\n"
#define lowbit(m) (-m&m)
#define yes cout<<"YES\n"
#define no cout<<"NO\n"
#define yi first
#define er second
using namespace std;
typedef long long ll;
typedef pair PII;
typedef double db;
int n;
string s;
void solve()
{
cin>>n;
cin>>s;
int ans=0;
int d=0;
int last=-1;
for(int i=0;i=n)break;
if(s[i+1]==s[i])
{
int c=s[i]-'0';
if(c==last)continue;
d++;
last=c;
}
else ans++;
}
d=max(1,d);
cout<>T;
while(T--)solve();
return 0;
}
3,山峰和山谷;
题意:
直接模板做,注意在bfs循环里(!st[i][j] )的位置;
#include
#pragma GCC optimize(2)
#define rep1(i,a,n) for(ll i=a;ia;i--)
#define per2(i,n,a) for(ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pb push_back
#define endl "\n"
#define lowbit(m) (-m&m)
#define yes cout<<"YES\n"
#define no cout<<"NO\n"
#define yi first
#define er second
using namespace std;
typedef long long ll;
typedef pair PII;
typedef double db;
const int N=1e3+10;
int h[N][N];
int n;
int st[N][N];
int bfs(int x,int y)
{
queueq;
q.push({x,y});
st[x][y]=1;
bool sf=0,sg=0;
while(q.size())
{
auto t=q.front();q.pop();
int xx=t.yi,yy=t.er;
rep2(i,xx-1,xx+1)
rep2(j,yy-1,yy+1)
{
if(i<1||i>n||j<1||j>n)continue;
if(i==xx&&j==yy)continue;
if(h[i][j]!=h[xx][yy])
{
if(h[i][j]>h[xx][yy])sf=1;
else sg=1;
}
else if(!st[i][j])
{
q.push({i,j});
st[i][j]=1;
}
}
}
if(sf&&sg)return 0;
if(sf&&!sg)return 2;
if(sg&&!sf)return 1;
else return 3;
}
signed main()
{
quick_cin();
int peak=0,vally=0;
cin>>n;
rep2(i,1,n)
rep2(j,1,n)cin>>h[i][j];
rep2(i,1,n)
rep2(j,1,n)
{
if(!st[i][j])
{
int x=bfs(i,j);
if(x==1)peak++;
if(x==2)vally++;
if(x==3)peak++,vally++;
}
}
cout<
5,Air Cownditioning B;
题意:给出a数组,ai代表第i头牛想要的值,给出b数组,bi为当前第i头牛的值;操作是选一段区间进行+1或者减1,使得每头牛都达到它想要的值,问最小的操作数;
这种题是套路题,就是搞差分做;
#include
//#pragma GCC optimize(2)
#define rep1(i,a,n) for(ll i=a;ia;i--)
#define per2(i,n,a) for(ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pb push_back
#define endl "\n"
#define lowbit(m) (-m&m)
#define yes cout<<"YES\n"
#define no cout<<"NO\n"
#define yi first
#define er second
using namespace std;
typedef long long ll;
typedef pair PII;
typedef double db;
const int N=1e6+10;
int a[N],b[N],c[N],d[N];
int n;
signed main()
{
quick_cin();
cin>>n;
rep2(i,1,n)cin>>a[i];
rep2(i,1,n)
{
cin>>b[i];
c[i]=a[i]-b[i];
}
rep2(i,1,n)d[i]=c[i]-c[i-1];
int c1=0,c2=0;
rep2(i,1,n)
{
if(d[i]<0)c1+=-d[i];
else c2+=d[i];
}
cout<
再来一个:
积木大赛;
这题其实是贪心,和铺设道路差不多;
但是也可以和差分沾点边,差分数组中的正数就是需要的操作数;
#include
//#pragma GCC optimize(2)
#define rep1(i,a,n) for(ll i=a;ia;i--)
#define per2(i,n,a) for(ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pb push_back
#define endl "\n"
#define lowbit(m) (-m&m)
#define yes cout<<"YES\n"
#define no cout<<"NO\n"
#define yi first
#define er second
using namespace std;
typedef long long ll;
typedef pair PII;
typedef double db;
const int N=1e6+10;
int a[N],b[N];
int n;
signed main()
{
quick_cin();
cin>>n;
int ans=0;
rep2(i,1,n)
{
cin>>a[i];
b[i]=a[i]-a[i-1];
}
rep2(i,1,n)
{
if(b[i]>0)ans+=b[i];
}
cout<
还有一个经典的模板题:
和牛那道题几乎一样,就是第一个值不用管了,因为只需要2~n之间的差分数组的值为0即可,就保证了1~n的数的值均为第一个值;
然后多了个不同结果;就是|x-y|+1;
和牛那道题的不同:牛那道题是需要整个差分数组的值均为0,这道题需要2~n之间的差分数组的值为0即可;
#include
//#pragma GCC optimize(2)
#define rep1(i,a,n) for(ll i=a;ia;i--)
#define per2(i,n,a) for(ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pb push_back
#define endl "\n"
#define lowbit(m) (-m&m)
#define yes cout<<"YES\n"
#define no cout<<"NO\n"
#define yi first
#define er second
#define int ll
using namespace std;
typedef long long ll;
typedef pair PII;
typedef double db;
const int N=1e6+10;
int a[N],b[N];
int n;
signed main()
{
quick_cin();
cin>>n;
int ans=0;
int cz1=0,cz2=0;
rep2(i,1,n)
{
cin>>a[i];
b[i]=a[i]-a[i-1];
}
rep2(i,2,n)
{
if(b[i]>0)cz1+=b[i];
else cz2+=-b[i];
}
cout<
6,bfs保存最短路径;
就是用PII fa[][]来保存当前位置的上一层的结点,也就是父亲;
#include
#pragma GCC optimize(2)
#define rep1(i,a,n) for(ll i=a;ia;i--)
#define per2(i,n,a) for(ll i=n;i>=a;i--)
#define quick_cin() cin.tie(0),cout.tie(0),ios::sync_with_stdio(false)
#define memset(a,i,b) memset((a),(i),sizeof (b))
#define memcpy(a,i,b) memcpy((a),(i),sizeof (b))
#define pb push_back
#define endl "\n"
#define lowbit(m) (-m&m)
#define yes cout<<"YES\n"
#define no cout<<"NO\n"
#define yi first
#define er second
using namespace std;
typedef long long ll;
typedef pair PII;
typedef double db;
const int N=1e3+10;
PII fa[N][N];
bool st[N][N];
int a[N][N];
int n;
int dx[]={-1,0,1,0},dy[]={0,1,0,-1};
void bfs()
{
queueq;
q.push({0,0});
st[0][0]=1;
bool flag=0;
while(q.size())
{
auto t=q.front();q.pop();
rep1(i,0,4)
{
int x=dx[i]+t.yi,y=dy[i]+t.er;
if(x>=0&&x=0&&yqq;
qq.push({n-1,n-1});
while(1)
{
auto t=qq.top();
if(t.yi==0&&t.er==0)break;
auto c=fa[t.yi][t.er];
qq.push({c.yi,c.er});
}
while(qq.size())
{
auto t=qq.top();qq.pop();
cout<>n;
rep1(i,0,n)
rep1(j,0,n)cin>>a[i][j];
bfs();
return 0;
}