zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 86 (Rated for Div. 2)

    A 当b>2*a时每次只减一个数会花费更少,否则先同减到其中一个数为0再计算会更少。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=200010;
    int t,n,m;
    ll x,y,a,b;
    int main()
    {
    	cin>>t;
    	while(t--)
    	{
    		cin>>x>>y>>a>>b;
    		ll ans=0;
    		ans+=min(x,y)*b;
    		ans+=(max(x,y)-min(x,y))*a;
    		cout<<min(ans,(x+y)*a)<<endl;
    	}
    	return 0;
    }
    

    还有一种思路是:关于同减次数x的总花费是个单谷函数,所以可以三分。

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    ll t,a,b,x,y;
    ll check(ll c)
    {
    	return c*b+abs(x-c)*a+abs(y-c)*a;
    }
    int main()
    {
    	cin>>t;
    	while(t--)
    	{
    		cin>>x>>y>>a>>b;
    		ll l=0,r=max(x,y);
    		while(l<r)
    		{
    			int mid1=l+(r-l)/3;
    			int mid2=r-(r-l)/3;
    			if(check(mid1)<check(mid2)) r=mid2-1;
    			else l=mid1+1;
    		}
    		cout<<check(l)<<endl;
    	}
    }
    

    B 如果t中只有一种字符那么它的周期k就是1已经最小了直接输出,否则周期不可能为1,但是周期为2是一定构造出来的,01交替即可,所以将相邻的两个相同字符中间加一个其他字符就可以了。(直接输出n个01也可以)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1010;
    int t,n,m;
    string s,st;
    int main(){
    	cin>>t;
    	while(t--){
    		cin>>s;
    		bool flag=1;
    		for(int i=0;i<s.size()-1;i++)
    			if(s[i]!=s[i+1])
    			{
    				flag=0;
    				break;
    			 } 
    		if(!flag) 
    		{
    			for(int i=0;i<s.size();i++)
    				if(i<s.size()-1)
    				{
    					st.push_back(s[i]);
    					if(s[i]==s[i+1])
    					{
    						if(s[i]=='1') st.push_back('0');
    						else st.push_back('1');
    					}
    				}
    				else st.push_back(s[i]);
    			cout<<st<<endl;
    			st.clear();//记得清空
    		}
    		else cout<<s<<endl; 
    	}
    	return 0;
    }
    

    C 统计再区间[li,ri]之间x的个数,x满足的条件是( (x%b)%a) != ( (x%a)%a)。
    可以打表找规律:令Max=max(a,b),Lcm=lcm(a,b) , 满足条件的x都有一个共性
    x%Lcm在区间 [Max,Lcm)内。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1010;
    int t,n,m,a,b;
    string s,st;
    ll get(ll l,int x,int y)//统计1到l满足条件的个数
    {
    	return l/y*(y-x)+max(0ll,l%y-x+1);
    }
    int main(){
    	cin>>t;
    	while(t--){
    		cin>>a>>b>>n;
    		int x=max(a,b),y=a*b/__gcd(a,b);
    		while(n--)
    		{
    			ll l,r;
    			cin>>l>>r;
    			cout<<get(r,x,y)-get(l-1,x,y)<<endl;
    		}
    	}
    	return 0;
    }
    

    D 又是一道阅读理解。已知一个测试样例有n个数组,每个数组的长度不超过k,第i数组的长度是mi,让你把这一个测试样例分成多个,每个样例中长度大于等于i的数组数量不超过ci。
    因为ci统计的是大于等于,所以先放长度最大的数组,这样放的时候已经放过的数组长度一定大于等于当前数组,所以当放第i个数组时如果样例中的数组数量a大于等于c[m[i]]时就不能放到这个样例了,因为放进去后大于等于m[i]的数量就是a+1一定大于等于c[m[i]]了,不满足题意。
    还要使测试样例尽可能的少,所以就要让每个样例里面尽可能多,但是会有一个最大限制c[1],因为所有数组长度一定大于等于1,所以每个样例最多有c[1]个数组。
    每个样例尽可能得多放,所以遍历ans个样例找第一个满足(数组数量小于c[m[i]])的样例,将m[i]放进去,如果找不到就再开一个样例。暴力去找的话肯定会超时,我们每次都放到第一个满足的样例,所以数组数量是单减的,在单减序列中找第一个小于某个数的位置可以用二分(可以自己写,也可以调用库函数),num[i]统计第i个样例中数组数量的负值,找第一个大于 -c[m[i]]的位置就可以了,如果超出ans,就再加一个样例。
    关于单减简单证明一下,不是太严谨:

    假设可以构造出来这样的单增样例:
    a b
    c d e(具体是几无所谓)
    因为e可以放到第二行,那么c[e]一定大于等于3,就是说e可以放到数量小于3的行,第一行也是可以的,那么这个例子就与 我们希望的将每个数放到第一个满足的样例相矛盾了。所以就是单减的了。

    看了一下大佬的思路,首先确定最少需要多少个样例,然后依次将每个数放进样例就可以了,思路很简单,代码更简单,tql

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=200010;
    int t,n,k,a,b;
    int c[N],m[N];
    vector<int> ve[N];
    int num[N];
    int ans=1;
    int main(){
    	scanf("%d%d",&n,&k);
    	for(int i=1;i<=n;i++) scanf("%d",m+i);
    	for(int i=1;i<=k;i++) scanf("%d",c+i);
    	sort(m+1,m+n+1);
    	int l=1;//l表示还能放数组的最小样例
    	for(int i=n;i;i--)//倒序枚举先放最大的
    	{
    		int x=upper_bound(num+l,num+ans+2,-c[m[i]])-num;//num[ans+1]=0,可以直接二分
    		if(x<=ans)
    		{
    			ve[x].push_back(m[i]);
    			num[x]--;
    			if(ve[x].size()==c[1]) l=x+1;//最多可以放c[1]个
    		}
    		else ve[++ans].push_back(m[i]),num[x]--;
    	}
    	printf("%d
    ",ans);
    	for(int i=1;i<=ans;i++)
    	{
    		printf("%d ",ve[i].size());
    		for(int j=0;j<ve[i].size();j++)
    			printf("%d ",ve[i][j]);
    		puts(""); 
    	}
    	return 0;
    }
    
  • 相关阅读:
    Java如何编写自动售票机程序
    install windows service
    redis SERVER INSTALL WINDOWS SERVICE
    上传文件
    This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.
    解决Uploadify上传控件加载导致的GET 404 Not Found问题
    OracleServiceORCL服务不见了怎么办
    Access to the temp directory is denied. Identity 'NT AUTHORITYNETWORK SERVICE' under which XmlSerializer is running does not have sufficient permiss
    MSSQL Server 2008 数据库安装失败
    数据库数据导出成XML文件
  • 原文地址:https://www.cnblogs.com/neflibata/p/12871746.html
Copyright © 2011-2022 走看看