CUGBACM19级暑假训练#3(数据结构基础专题)

写在前面

        时间于6.28-6.30开了一场专题训练,将自己的思路与过程写在下面,以有效监督自己,提高效率,好好反思。

题解

A-Time to Raid Cowavans

div1D题劝退 待补

B-A and B and Compilation Errors

思路:在第一行所有出现的n个数字中,在map中全部+2,因为你剩下两行是你取出一个a,再取出一个b,那么a以后不会在出现(这里出现不是这个数字,而是取出的那个特殊的,因为会有重复的),b会在第二行出现一次,第三行不会出现。所以:我们在接下来两行每次出现就-1,看还剩下什么。 

#include<bits/stdc++.h>
using namespace std;
const int N = 100007;
int n,a[N],ans1,ans2,x;
map<int,int> mp; 
int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	for (int i=1;i<=n;i++)
	{
		cin>>a[i];
		mp[a[i]]+=2;
	}
	for (int i=1;i<n;i++)
	{
		cin>>x;
		mp[x]--;
	}
	for (int i=1;i<n-1;i++)
	{
		cin>>x;
		mp[x]--;
	}
	for (int i=1;i<=n;i++)
	{
		if (mp[a[i]]==1) ans2=a[i];
		if (mp[a[i]]==2) ans1=a[i];
		if (mp[a[i]]>2) ans1=ans2=a[i];//可能会有重复的 都为一个数字
	}
	cout<<ans1<<endl<<ans2;
}
/*
3 3 3
2 2 2
2 1 1
2 1 0
*/

C - Color the Fence

思路:不能全为贪心,加入v=15,'1'需要4,'5'需要5,‘9'需要6,如果是贪心,那么只会有“111”,但是同样用5的话,也不行,因为我可以在“555”的基础上,减少最后一位的’5‘,让其变成’1‘,这样就多出来了一个可以将最左边的’5‘换成’9‘,使其“555”->“951”进而最大。只需要再扫一遍即可。

D - Snacktower

思路:div2A,水题。就是一直扫,碰见最大的就开始处理,具体处理是从大往下找,找打还未出现的最大的(因为你要等下一个最大的掉下来才能堆)

#include<bits/stdc++.h>
using namespace std;
const int N=100007;
int n,x,tmp;
bool exist[N];
int main()
{
	ios::sync_with_stdio(false);
	cin>>n;
	tmp=n;
	for (int i=1;i<=n;i++)
	{
		cin>>x;
		exist[x]=1;//标志数组
		while (exist[tmp])//如果当前的存在
		{
			cout<<tmp<<" ";
			tmp--;//一直往下循环找
		}
		cout<<endl;
	}
}

E - Stripe 

思路:就是个划分,前缀和处理

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll a[100005],sum;
int main()
{
	int n;
	cin>>n;
    for(int i=1;i<=n;i++)
	{
        cin>>a[i];
        a[i]=a[i]+a[i-1];
    }
    for(int i=2;i<=n;i++)
        if (a[n]-a[i-1]==a[i-1])sum++;
    cout<<sum<<endl;
}

 F - Queue

待我多开一个博客好好写这个题

G - Mike and Feet

 待我多开一个博客好好写这个题

H - Longest Regular Bracket Sequence

 待我多开一个博客好好写这个题

I - Maximum Submatrix 2

待我...还是在这写了吧。

题意:给你一个n*m的01矩阵,求最大面积的'1'的矩阵(在列不动,行随意动的情况下)

思路:类似于前缀和预处理一下,但是不同的是我们a[i][j]表示的是a[i][j]往左有多个连续的1,如果断了那么从0开始(因为面积需要全部是1)。然后我们将每一列开始排序,比如{2,3,6,4,2,1,0,}取出来排序成{6,4,3,2,2,1,0},然后开始取max。

取max操作为b[i]*i(长乘以宽),不用取min的宽,因为当前的b[i]是降序排列。ans即可得出。

#include<bits/stdc++.h>
using namespace std;
const int N = 5000+7;
int n,m,a[N][N],b[N],ans,minn;
char c;
int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
		{
			cin>>c;
			if (c=='1')
				a[i][j]=a[i][j-1]+1;
			else
				a[i][j]=0;
		}
	for (int j=1;j<=m;j++)
	{
		for (int i=1;i<=n;i++)
			b[i]=a[i][j];
		sort(b+1,b+1+n,greater<int>());
		for (int i=1;i<=n;i++)
			if (b[i]==0) break;
			else ans=max(ans,i*b[i]);
	}
	cout<<ans;
}

L - Cells Not Under Attack

思路:水题,直接看代码,好吧,统计列和行

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 100007;
int h[N],l[N],x,y,tmp,n,m,xx,yy;
signed main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	tmp=n*n;
	xx=n;yy=n;
	for (int i=1;i<=m;i++)
	{
		cin>>x>>y;
		if (h[x]==0) h[x]=1,xx--;
		if (l[y]==0) l[y]=1,yy--;
		cout<<xx*yy<<" ";
	}
}

S - Subsegments

是个div2的E,不错不错

思路:用map统计个数,设定一个set——s,用来表示当前区间内的数字,因为set是排序的,我们只需要输出*rbegin()就行(我用*end()就错了...)

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
int n,k,a[N];
map<int,int> mp;
set<int> s;
int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>k;
	for (int i=1;i<=n;i++) cin>>a[i];
	for (int i=1;i<k;i++)//预处理 其实也可以在下面的循环一起写 写个if
	{
		mp[ a[i] ]++;//个数+1
		if (mp[ a[i] ]==1) s.insert(a[i]);//如果只有一个 s插入
		else if (s.count(a[i])) s.erase(a[i]);//如果s中已经有 但是又出现了 删除
	}
	for (int i=k;i<=n;i++)
	{
		mp[ a[i] ]++;
		if (mp[ a[i] ]==1) s.insert(a[i]);
		else if (s.count(a[i])) s.erase(a[i]);//这三行同上预处理
		mp[ a[i-k] ]--;//删除头
		if (mp[ a[i-k] ]==1) s.insert(a[i-k]);//删除头
		else if (mp[ a[i-k] ]== 0) s.erase(a[i-k]);
		if (s.size()==0) cout<<"Nothing"<<endl;//set是空的 那么就输出nothing
		else cout<<*s.rbegin()<<endl;//输出最后一个 set是排序的
	}
}

V - Queries about less or equal elements

思路:水题...第一个秒的。给出a,b数组,问b数组每一个在a中有多少比他小的,sort一遍直接二分,b数组都不需要开

#include<bits/stdc++.h>
using namespace std;
const int N = 200007;
int n,m,a[N],x;
int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for (int i=1;i<=n;i++)
		cin>>a[i];
	sort(a+1,a+1+n);
	for (int i=1;i<=m;i++)
	{
		cin>>x;
		cout<<(upper_bound(a+1,a+1+n,x)-a)-1<<" ";
	}
}

反思

        有的时候感觉自己写不出,实际上真的写不出可能写的出,唉,多刷题多补题多总结吧,多写博客,这一次写下来,感觉以后还是分开写吧

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值