@(codeforces)[CHC]
《Alive》
有两个游戏柄和一个充电器,初始时两个游戏柄的电量分别为a
%和b
%,某个游戏柄如果连接充电器的话每分钟可以提升1
%的电量,如果不连接充电器每分钟掉2
%的电量,如果某游戏柄的电量<=0就不能玩。问最多能玩多久?
1≤a1,a2≤100
输入:
1 1
输出:
0
输入:
3 5
输出:
6
输入:
4 4
输出:
5
.
.
.
.
.
.
.
.
.
范围小。。枚举。。策略是贪心。。哪个电量少就给哪个充电。。
//author: CHC
//First Edit Time: 2016-03-12 11:29
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAXN=1e+4;
const int MAXM=1e+5;
const int INF = numeric_limits<int>::max();
const LL LL_INF= numeric_limits::max();
int main()
{
int a,b;
while(~scanf("%d%d",&a,&b)){
int ans=0;
while(a>0&&b>0){
if(a2;
if(a<0)--ans;
//printf("%d %d\n",a,b);
}
printf("%d\n",ans);
}
return 0;
}
如果数据量大,就是不用枚举或者单位为毫秒或者微秒。。 1≤a,b≤1010 怎么求?
给一个长度为n( 1≤n≤1000 )的数组,对于每个数字 1≤ai≤1000 ,把这个数组的顺序重新组合后求最多有多少对 ai−1<ai
输入:
5
20 30 10 50 40
输出:
4
输入:
4
200 100 100 200
输出:
2
.
.
.
.
.
.
.
.
.
.
范围小。。哈系,枚举。。
//author: CHC
//First Edit Time: 2016-03-12 13:05
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAXN=1e+4;
const int MAXM=1e+5;
const int INF = numeric_limits<int>::max();
const LL LL_INF= numeric_limits::max();
int has[1010];
int n;
int main()
{
while(~scanf("%d",&n)){
memset(has,0,sizeof(has));
for(int i=0,x;iscanf("%d",&x);
++has[x];
}
int ans=0;
for(int i=0;i<1000;i++){
int cnt=0;
for(int j=1;j<=1000;j++){
cnt+=(has[j]>0);
has[j]--;
}
if(cnt<=1)break;
ans+=cnt-1;
}
printf("%d\n",ans);
}
return 0;
}
如果范围很大,不能使用枚举该如何做?
在二维平面上,有n个点( 1≤n≤200000 ),问有多少对点(i,j)( i<j )可以使得以下成立
|xi−xj|+|yi−yj|=(xi−xj)2+(yi−yj)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾√2
|xi|,|yi|≤109
输入:
3
1 1
7 5
1 5
输出:
2
输入:
6
0 0
0 1
0 2
-1 1
0 1
1 1
输出:
11
.
.
.
.
.
.
.
.
.
.
.
.
计算某行的组合+某列的组合-自己和自己的组合
//author: CHC
//First Edit Time: 2016-03-12 13:26
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAXN=200000+100;
const int INF = numeric_limits<int>::max();
const LL LL_INF= numeric_limits::max();
struct point {
int x,y;
}cs[MAXN];
int cmp(const point &x,const point &y)
{
if(x.x!=y.x)return x.xreturn x.yint A[MAXN*2];
int n;
int tmp[MAXN*2];
int main()
{
while(~scanf("%d",&n)){
for(int i=0;iscanf("%d%d",&cs[i].x,&cs[i].y);
A[i<<1]=cs[i].x;
A[i<<1|1]=cs[i].y;
}
sort(A,A+(n<<1));
int tn=unique(A,A+(n<<1))-A;
memset(tmp,0,sizeof(tmp));
for(int i=0;iint pos = lower_bound(A,A+tn,cs[i].x)-A;
++tmp[pos];
}
LL ans = 0;
for(int i=0;iint pos = lower_bound(A,A+tn,cs[i].x)-A;
if(tmp[pos]){
//printf("x:%d %d\n",cs[i].x,tmp[pos]);
ans += 1LL*(tmp[pos]-1)*tmp[pos]/2;
tmp[pos]=0;
}
}
for(int i=0;iint pos = lower_bound(A,A+tn,cs[i].y)-A;
++tmp[pos];
}
for(int i=0;iint pos = lower_bound(A,A+tn,cs[i].y)-A;
if(tmp[pos]){
//printf("y:%d %d\n",cs[i].y,tmp[pos]);
ans += 1LL*(tmp[pos]-1)*tmp[pos]/2;
tmp[pos]=0;
}
}
//printf("%lld\n\n",ans);
sort(cs,cs+n,cmp);
int cnt=1;
int tx=cs[0].x,ty=cs[0].y;
for(int i=1;i//printf("h:%d %d\n",cs[i].x,cs[i].y);
if(tx==cs[i].x&&ty==cs[i].y){
++cnt;
//printf("%d %d %d\n",cs[i].x,cs[i].y,cnt);
}
else {
ans-=1LL*(cnt-1)*cnt/2;
cnt=1;
tx=cs[i].x;ty=cs[i].y;
}
}
ans-=1LL*(cnt-1)*cnt/2;
printf("%lld\n",ans);
}
return 0;
}
/*
* #1 : 越界
* */
有n张图片在手机里( 1≤n≤5∗105 ),看一张图片需要1秒,看相邻的图片需要左划或者右划,左划或者右划需要a秒,旋转一张图片需要b秒,手机是竖着的,有的图片需要横着看,不能旋转手机,只能旋转图片,如果一张图片看过,那么再次看它会被忽略,一开始打开手机看到的是第一张图片
给n,a,b,T,问最多能看多少张图片
输入:
4 2 3 10
wwhw
输出:
2
输入:
5 2 4 13
hhwhh
输出:
4
输入:
5 2 4 1000
hhwhh
输出:
5
输入:
3 1 100 10
whw
输出:
0
.
.
.
.
.
.
.
.
.
.
.
只有四种情况:
1. 从第一张一直往右边看
1. 从第一张一直往左边看
1. 从第一张先往左边看,再往右边看
1. 从第一张先往右边看,再往左边看
只需要固定一个点,然后二分求就可以了复杂度 O(nlogn) 。。注意这里如果不预处理,复杂度会退化成 O(n2logn)
//author: CHC
//First Edit Time: 2016-03-12 19:30
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int MAXN=500000 * 2 + 1000;
const int INF = numeric_limits<int>::max();
const LL LL_INF= numeric_limits::max();
int n,a,b,T;
char str[MAXN];
LL pre[MAXN];
LL Calc(int l,int r){
LL cnt = 0;
if(l == 0)
cnt += (r-l)*a;
else
cnt += (r-l)*a + min(n-l,r-n)*a;
/*
for(int i=l;i<=r;i++){
cnt += ((str[i]=='h')?0:b) + 1;
}
*/
return cnt + pre[r+1] - pre[l];
//return cnt;
}
int main()
{
while(~scanf("%d%d%d%d",&n,&a,&b,&T)){
scanf(" %s",str);
for(int i = 0;i < n;i++)str[i+n]=str[i];
pre[0] = 0;
int tn = n<<1;
for(int i = 1;i <= tn;i++)pre[i] = pre[i-1] + (str[i-1]=='h'?0:b) + 1;
int num = 0;
for(int i = 0;i <= n;i++){
int l = i , r = i + n - 1 ;
if(l != 0) l = n;
while(l <= r){
int mid = (l + r) >> 1;
LL val = Calc(i,mid);
if(val <= (LL)T){
num = max(num,mid-i+1);
//printf(":%d %d %.*s\n",i,mid,mid-i+1,str+i);
l = mid + 1;
}
else r = mid -1;
}
}
printf("%d\n",num);
}
return 0;
}