Codeforces Round #645 (Div. 2) A~D

水题,贪心,一个灯亮两个格子就行,所以就是 (m*n+1)>>1


#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL N=12;
int main(int argc, char const *argv[])
{
	// #define DEBUG
    	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	LL _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	while(_--){
		LL a,b;
		cin>>a>>b;
		cout<<((a*b+1)>>1)<<endl;
	}
	return 0;
}

贪心,直接一次把能叫的最多人叫去,排序后做就行

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL N=1e5+10;
int a[N];
int main(int argc, char const *argv[])
{
	// #define DEBUG
    	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	LL _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	while(_--){
		int n;
		cin>>n;
		rep(i,0,n)
			cin>>a[i+1];
		sort(a+1,a+n+1);
		int ans = 1; //自己
		int i=n;
		while(i>0&&a[i]>i)
			i--;
		ans += i;
		cout<<ans<<endl;
	}
	return 0;
}

观察后可以发现,所有不同的值最后是连续的,因为每提前向下一次,比往右一次收益大1
所以可以求最大值和最小值,看之间共多少数,但是直接猜了个差距相乘加1就对了,迷惑。


#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()

int main(int argc, char const *argv[])
{
	// #define DEBUG
    	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	LL _;
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>_;
	while(_--){
		LL x1,y1,x2,y2;
		cin>>x1>>y1>>x2>>y2;
		LL gapx = x2-x1;
		LL gapy = y2-y1;
		cout<<gapy*gapx+1<<endl;
	}
	return 0;
}

观察可以发现,使得结束日期在一个月的末尾,收益最高
所以求前缀和之后二分起点就可以


#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(LL i=(j); i<(k); ++i)
#define pb push_back
#define PII pair<LL,LL>
#define PLL pair<long long, long long>
#define ini(a,j) memset(a,j,sizeof a)
#define rrep(i,j,k) for(LL i=j; i>=k; --i)
#define fi first
#define se second
#define LL long long
#define beg begin()
#define ed end()
#define all(x) x.begin(),x.end()
const LL N=2e5+10;
LL a[2*N];
LL b[2*N];
LL c[N];
int main(int argc, char const *argv[])
{
	// #define DEBUG
    	#ifdef DEBUG
		freopen("1.dat","r",stdin);
		freopen("ans.dat","w",stdout);
	#endif
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	LL n,x;
	cin>>n>>x;
	rep(i,0,n) cin>>c[i];
	a[0]=c[0];
	b[0]=((c[0]+1)*c[0])>>1;
	rep(i,1,2*n){
		b[i] = (((c[i%n]+1)*c[i%n])>>1)+b[i-1];
		a[i] = c[i%n]+a[i-1]; //计算天数
	}
	//如果我在某个月到,那么应该选择哪个月呢
	LL ans = 0;
	rep(i,0,n){  //在这个月的终点结束
		LL l = i;
		LL r = i+n;
		LL temp = r;
		while(r>=l){
			LL mid = (l+r)>>1;
			if(a[i+n]-a[mid]>=x){
				l = mid+1;
			}else{
				temp = mid;
				r = mid-1;
			}
		}
		LL cnm = x-(a[i+n]-a[temp]);
		// cout<<cnm<<" "<<i+n<<" "<<temp<<endl;
		LL rem = ((c[temp%n]+1)*c[temp%n])>>1;
		rem -= ((c[temp%n]-cnm+1)*(c[temp%n]-cnm))>>1;
		// cout<<rem<<endl;
		// cout<<b[i+n]-b[temp]<<endl;
		ans = max(ans,b[i+n]-b[temp]+rem);
	}
	cout<<ans<<endl;
	return 0;
}
posted @ 2020-05-27 08:46  CrosseaLL  阅读(205)  评论(0编辑  收藏  举报