538B.Quasi Binary、1380C.Create The Teams、 AtCoder Beginner Contest 223;

中午upc,只出了一道。
下午刷了两道1400,晚上Atcoder一场。


E: Rescue Mission(前缀和,map)

题意:

给出长度为 n 的数列,求每一个位置往后延伸的最短距离,使得这个区间中的所有数为10的倍数。

思路:

和之前做过的求总和为x的倍数的最大区间,或者区间个数这样的题 思路相同。

处理前缀和,前缀和取模,判断当前的值是否在前面出现过。如果是,那么中间这一段总和就为x的倍数了。

这里就是要把前面一次该数出现的位置+1这个位置 的答案赋值为这一区间长度就行了。

注意标记0位置为数0出现的位置。

Code:

const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];
int f[N];

int main(){
	Ios;
	cin>>n;
	
	mp[0]=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[i]=(a[i]+a[i-1])%10;
		
		f[i]=-1;
		if(!mp.count(a[i])) mp[a[i]]=i;
		else{
			f[mp[a[i]]+1]=i-mp[a[i]];
			mp[a[i]]=i;
		}
	}
	
	for(int i=1;i<=n;i++) cout<<f[i]<<" ";
	
	return 0;
}

538B. Quasi Binary(思维,进制)

题意:

一个十进制数可以由若干个 每位只包含0或1的十进制数 相加组成。
给出一个数n,能组成的n的数最少为多少个?依次输出。

思路:

进制的角度来看。遍历n的每一位;
如果这一位的数 x 不为0,那么组成n的一个数这一位就为 1,将 x - -,答案串+‘1’;
如果 x 为 0,那么组成 n 的所有数这一位都为 0,答案串+‘0’。
将答案串转化为数字便是一个答案数。

同理,二进制似乎也可以这样做。因为是让组成数最少,那么就需要每一位尽可能的大。所以如果这一位不为0,就把答案数的这一位设为1。

而另一种贪心做法:每次都选不超过n的最大的01数,那么减到最后剩下的就可能不是比较大的01数了,只能由1拼成,这样个数就变多了。

关键是思维的转化。

Code:

const int N = 2000010, mod = 1e9+7;
int T, n, m, a[N];
string s;
int ans[N];

int main(){
	cin>>n;
	
	s=to_string(n);
	int cnt=0;
	
	while(1)
	{
		string t;
		int flag=0;
		for(int i=0;i<s.size();i++)
		{
			int x=s[i]-'0';
			if(x) t+='1',x--,flag=1;
			else t+='0';
			
			s[i]=x+'0'; 
		}
		if(!flag) break;
		cnt++;
		ans[cnt]=stoi(t);
	}
	cout<<cnt<<endl;
	for(int i=1;i<=cnt;i++) cout<<ans[i]<<" ";
	
	return 0;
}

1355D. Game With Array(模拟)

题意:

要把n个数选出若干组。
要求每一组中的 人数*这组中的最小的a[i] ≥ x。
问,最多分多少组?

思路:

为了使得每组的人数更少,要使得每组中最小的a[i]更大。
从大到小将a[i]排序。
遍历每个位置,看当前数能不能作为一组中最小的一个数。
即,看前面是否有x/a[i]上取整个数没有在集合中。

Code:

const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];

int main(){
	Ios;
	cin>>T;
	while(T--)
	{
		cin>>n>>m;
		for(int i=1;i<=n;i++) cin>>a[i];
		
		sort(a+1,a+n+1,greater<int>());
		
		int ans=0,cnt=0;
		for(int i=1;i<=n;i++)
		{
			int x=a[i];
			int t=(m+a[i]-1)/a[i];
			cnt++;
			if(cnt>=t) cnt=0,ans++;
		}
		cout<<ans<<endl;
	}
	
	return 0;
}

还有一道还没出,明天再看吧。



AtCoder Beginner Contest 223

D - Restricted Permutation(拓扑排序,优先队列)

题意:

输出字典序最小的拓扑序列。

思路:

把队列换成优先队列,每次都先把入度为0的,最小的点输出。

当时没想出来。。只想着加边,加边。。

这是第二次遇到字典序用优先队列的了!

还有就是:拓扑序列输出顺序就是出队顺序,出队来更新其他点的顺序。

Code:

const int N = 200010, mod = 1e9+7;
int T, n, m, a[N];
int e[N*2],ne[N*2],h[N],idx;
int ru[N],que[N*2];
int ans[N],cnt=0;

void add(int x,int y){
	e[idx]=y,ne[idx]=h[x],h[x]=idx++;
}

void tpsort()
{
	priority_queue<int,vector<int>,greater<int> > que;
	
	for(int i=1;i<=n;i++){
		if(!ru[i]) que.push(i);
	}
	
	while(que.size())
	{
		int x=que.top();que.pop();
		ans[++cnt]=x;
		
		for(int i=h[x];i!=-1;i=ne[i])
		{
			int tx=e[i];
			ru[tx]--;
			if(!ru[tx]) que.push(tx);
		}
	}
	
	int flag=0;
	for(int i=1;i<=n;i++) if(ru[i]>0) flag=1;
	
	if(flag) cout<<-1;
	else{
		for(int i=1;i<=cnt;i++) cout<<ans[i]<<' ';	
	}
}

int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) h[i]=-1;
	
	while(m--)
	{
		int x,y;cin>>x>>y;
		add(x,y);
		ru[y]++;
	}
	
	tpsort();
	
	return 0;
}

最近有点飘了!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值