22/5/12

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,山峰和山谷;

题意:

22/5/12_第1张图片

直接模板做,注意在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<

再来一个:

积木大赛;

题意:22/5/12_第2张图片

这题其实是贪心,和铺设道路差不多;

但是也可以和差分沾点边,差分数组中的正数就是需要的操作数;

#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<

还有一个经典的模板题:

IncDec Sequence 

题意:22/5/12_第3张图片

 和牛那道题几乎一样,就是第一个值不用管了,因为只需要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;
}

 

 

你可能感兴趣的:(蓝桥杯,c++,算法)