Codeforces Round #653 (Div. 3)A-B-C-D-E1

Codeforces Round #653 (Div. 3)傳送門

A.Required Remainder

題意:在1-n中找到一個k,求符合條件k%x=y的最大k。
題解:在[1,n]中,找到x的最大倍數+y,這樣就保證了k%x=y,再判斷k+y是否在[1,n]中,若不在只需要再減去一個x。

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define endl  '\n'
using namespace std;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
    int t;cin>>t;
    while(t--)
    {
      	ll ans=0,x,y,n;cin>>x>>y>>n;
      	ans=n/x*x+y;
      	if(ans>n)ans-=x;  
      	cout<<ans<<endl;
    }
    return 0;
}

B. Multiply by 2, divide by 6

題意:給你一個n,你可以每次進行一次n*2或n/6操作,求最小需要多少次操作纔可以使得n變成1,若不能則輸出-1
題解:直接暴力模擬,6不是n的因子時就乘2,如果n被除到0就break

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define endl  '\n'
using namespace std;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
    int t;cin>>t;
    while(t--)
    {
      ll n,ans=0;cin>>n;
      int f=0;
	  while(n>=1)
	  {
		  	if(n==1){
		  		f=1;break;
		    }
		  	if(n%6!=0)n*=2;
		  	else n/=6;
		  		ans++;
	  }
	  	if(f)cout<<ans<<endl;
	  	else cout<<-1<<endl;
    }
    return 0;
}

C. Move Brackets

題意:匹配()括號,如不能匹配成功,則可以進行移動,可移動到任意位置,求需要移動的最小次數
題解:統計左括號(和)右括號,左++右–,當小於0即出現了右括號)但是前面已經沒有左括號(可以匹配時才需要移動一次位置。

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define endl  '\n'
using namespace std;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
    int t;cin>>t;
    while(t--)
    {
      	ll n,k=0,ans=0;cin>>n;
      	string s;cin>>s;
      	for(int i=0;i<n;i++)
      	{
      		if(s[i]=='(')k++;
			else {
				if(k)k--;
				else ans++;
			}	
		}
		cout<<ans<<endl;
    }
    return 0;
}

D. Zero Remainder Array

題意:一個長度n的a數組,x從x=0開始不斷遞增加1,可以進行操作①從數組a中挑一個a[i]=a[i]+x,然後x遞增1,操作②不挑數組a的元素加x,x直接遞增1。求你最少需要進行多少次操作使得數組a中的所有元素變成k的倍數。
題解:因爲x是不斷遞增的,且知道x累加到≥k時其實對數組a中每個元素a[i]變成k的倍數的貢獻只有x%k,故此處可以看成x不斷的從[0,k-1]循環,直接用map統計數組a中每個元素a[i]最少還需要加多少才成變成k的倍數,選出map中的最大值-1即是需要循環的次數,再加上最後一次未完整循環的最大值。
注意:會卡數組,會卡unordered_map,所以需要用map

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define _for(i,a,b) for(int i = (a);i<(b);i++)
#define endl  '\n'
using namespace std;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
    int t;cin>>t;
    while(t--)
    {
      ll n,k,x;cin>>n>>k;
      map<ll,ll>a;
      ll mx=0,l=0;
	  for(ll i=0;i<n;i++)
	  {
	  	cin>>x;
	  	if(k-x%k!=k){
	  		a[k-x%k]++;
	  		if(mx<a[k-x%k])
	  		{
	  			mx=a[k-x%k];
	  			l=k-x%k;
			}
			else if(mx==a[k-x%k])l=max(l,k-x%k);
		  }
	  }
	  if(mx!=0)
	  cout<<(mx-1)*k+l+1<<endl;
	  else cout<<0<<endl;	
    }
    return 0;
}

E1. Reading Books (easy version)

題意:Alice 和Bob 兩人都需要看k本書,一共有n本書,看完每個本需要用t[i]
時間,a[i]和b[i],等於1時表示喜歡這本書,等於0時表示不喜歡這本書,Alice 和Bob 兩人只看自己喜歡的書,且兩人每次只能選一本書讀,若其中一人喜歡一人不喜歡,那就只有一人讀。求最少需要多少時間使得Alice 和Bob 兩人都讀完k本書。
題解:分別統計a[i]=b[i]=1,a[i]=0和b[i]=1,a[i]=1和b[i]=0。把a[i]=0和b[i]=1,a[i]=1和b[i]=0合併,相當於變成a[i]=b[i]=1,再加入到a[i]=b[i]=1中,然後用sort,前綴和選出前面k個小的。
需要注意的是,a[i]=0和b[i]=1,a[i]=1和b[i]=0這兩種情況不一定出現相同次數,所以能合併成a[i]=b[i]=1的對數是a[i]=0和b[i]=1,a[i]=1和b[i]=0情況的較小值。

#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define ll long long
#define endl  '\n'
using namespace std;
int main()
{
    ios::sync_with_stdio(0);cin.tie(0), cout.tie(0);
   ll n,k;cin>>n>>k;
   vector<ll>a,b,c;
   for(ll i=0;i<n;i++)
   {
   		ll t,x,y;cin>>t>>x>>y;
   		if(x==1&&y==1)
   			a.push_back(t);	
		if(x==1&&y==0)
			b.push_back(t);
		if(x==0&&y==1)
			c.push_back(t);
   }
   if(b.size()>c.size()) swap(b,c);
   if(a.size()+b.size()<k) cout<<-1;
   else {
	   sort(b.begin(),b.end());
	   sort(c.begin(),c.end());
	  for(ll i=0;i<b.size();i++)
	  	b[i]+=c[i]; 
	   sort(b.begin(),b.end());
	   for(ll i=0;i<b.size();i++)
	   	a.push_back(b[i]);
	   sort(a.begin(),a.end());
	   	ll ans=0;
	   	for(ll i=0;i<k;i++)
	   	ans+=a[i];
	   	cout<<ans;
   }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章