1:前面已經搞好了。
2:poj2965 這種開關問題一個點要麼點一次要麼不點,枚舉所有點的方案實行即可

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
char ss[10];
int main()
{
int d=0,tp=0;
for(int i=1;i<=4;i++)
{
scanf("%s",ss+1);
for(int j=1;j<=4;j++,tp++)
if(ss[j]=='+')d+=(1<<tp);
}
int max_line=(1<<16)-1,ans=999999,zt;
for(int i=0;i<=max_line;i++)
{
int k=d,sum=0;
for(int j=0;j<=15;j++)
{
if((i&(1<<j))>0)
{
sum++;
int h=j/4;
for(int _=0;_<=3;_++)k^=(1<<(h*4+_));
int l=j%4;
for(int _=0;_<=12;_+=4)k^=(1<<(l+_));
k^=(1<<(h*4+l));
}
}
if(k==0)
{
if(ans>sum)
ans=sum, zt=i;
}
}
printf("%d\n",ans);
int x=1,y=1;
for(int j=0;j<=15;j++)
{
if((zt&(1<<j))>0)printf("%d %d\n",x,y);
y++;if(y==5)y=1,x++;
}
return 0;
}
poj2965
3、4、10:手殘碼農題真心不想做,準備NOIP的時候再做吧
5:poj 3714 平面最近點對問題,分治解決,對于目前已有的最小值确定mid上下左右一個四邊形的範圍,合并區間時就判定這個四邊形範圍裡面的點即可,聞說這個點數是不會超過8個的。具體實行是在确定了橫坐标範圍後,把這些點取出,判定時将其按縱坐标排序,一個個求值,這個複雜度是n(logn)^2,假如用歸并排序順便把縱坐标排序會少一個log,但是實際上并沒有快多少。至于kdtree。。以後再說

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
struct point{double x,y;int z;}a[210000],t[210000];
bool cmp(point p1,point p2){return p1.x<p2.x;}
int tt[210000];
bool cmp2(int n1,int n2){return a[n1].y<a[n2].y;}
double getdis(int n1,int n2)
{
return sqrt( (double((a[n1].x-a[n2].x)*(a[n1].x-a[n2].x))) + (double((a[n1].y-a[n2].y)*(a[n1].y-a[n2].y))) );
}
double fenzi(int l,int r)
{
if(l==r)return (double(1<<30));
int mid=(l+r)/2;
double mmin=min(fenzi(l,mid),fenzi(mid+1,r));
int i=l,j=mid+1,p=l;
while(i<=mid&&j<=r)
{
if(a[i].y<=a[j].y)t[p++]=a[i++];
else t[p++]=a[j++];
}
while(i<=mid)t[p++]=a[i++];
while(j<=r) t[p++]=a[j++];
for(int i=l;i<=r;i++)a[i]=t[i];
int len=0;tt[++len]=mid;
for(int i=l;i<=r;i++)
if(( double(abs(a[i].x-a[mid].x)) )<mmin)tt[++len]=i;
for(int i=1;i<=len;i++)
for(int j=i+1,clc=0;j<=len&&clc<=7;j++,clc++)
if(a[tt[i]].z!=a[tt[j]].z)
mmin=min(mmin,getdis(tt[i],tt[j]));
return mmin;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y), a[i].z=0;
for(int i=n+1;i<=n*2;i++)
scanf("%lf%lf",&a[i].x,&a[i].y), a[i].z=1;
sort(a+1,a+2*n+1,cmp);
printf("%.3lf\n",fenzi(1,2*n));
}
return 0;
}
poj3714
6:bzoj1271 這道是好題啊!突破口一定是在隻有一個是奇數這個條件裡面的,那麼就是奇偶性的不同,這個時候并沒有想到字首和。知道這個以後就二分答案,看看字首和是奇數還是偶數就行了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
int n;
struct node
{
LL l,r,d;
}a[210000];
bool check(LL tp)
{
LL sum=0;
for(int i=1;i<=n;i++)
if(a[i].l<=tp)sum+=(min(a[i].r,tp)-a[i].l)/a[i].d+1;
return (sum%2==1);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld%lld",&a[i].l,&a[i].r,&a[i].d);
LL l=1,r=2147483647,ans=-1;
while(l<=r)
{
LL mid=(l+r)/2,u;
if(check(mid)==true)
{
r=mid-1;
ans=mid;
}
else l=mid+1;
}
if(ans==-1)printf("Poor QIN Teng:(\n");
else
{
LL c=0;
for(int i=1;i<=n;i++)
if(a[i].l<=ans&&ans<=a[i].r&&(ans-a[i].l)%a[i].d==0)c++;
printf("%lld %lld\n",ans,c);
}
}
return 0;
}
bzoj1271
7:poj3179 這題明顯就得寫個二維字首和嘛。。相應的就離散化一下。二分答案,然後兩個for一個枚舉行一個枚舉列的後界,前界盡量往前,這個while往前走就好。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int n,C;
struct node{int x,y;}a[510];
int lsxlen,lsylen,lsx[510],lsy[510];
void LSH()
{
lsxlen=0;
for(int i=1;i<=n;i++)lsx[++lsxlen]=a[i].x;
sort(lsx+1,lsx+lsxlen+1);
lsxlen=unique(lsx+1,lsx+lsxlen+1)-lsx-1;
for(int i=1;i<=n;i++)
a[i].x=lower_bound(lsx+1,lsx+lsxlen+1,a[i].x)-lsx;
lsylen=0;
for(int i=1;i<=n;i++)lsy[++lsylen]=a[i].y;
sort(lsy+1,lsy+lsylen+1);
lsylen=unique(lsy+1,lsy+lsylen+1)-lsy-1;
for(int i=1;i<=n;i++)
a[i].y=lower_bound(lsy+1,lsy+lsylen+1,a[i].y)-lsy;
}
int sum[510][510];
int getsum(int x,int y,int u,int v)
{
return sum[x][y]-sum[x][v-1]-sum[u-1][y]+sum[u-1][v-1];
}
bool check(int mid)
{
int rl=1;
for(int rr=1;rr<=lsxlen;rr++)
{
while(lsx[rr]-lsx[rl]>=mid)rl++;
int cl=1;
for(int cr=1;cr<=lsylen;cr++)
{
while(lsy[cr]-lsy[cl]>=mid)cl++;
if(getsum(rr,cr,rl,cl)>=C)return true;
}
}
return false;
}
int main()
{
scanf("%d%d",&C,&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
LSH();
memset(sum,0,sizeof(sum));
for(int i=1;i<=n;i++)sum[a[i].x][a[i].y]++;
for(int i=1;i<=lsxlen;i++)
for(int j=1;j<=lsylen;j++)
sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
int l=1,r=10000,ans;
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid)==true)
{
ans=mid;
r=mid-1;
}
else l=mid+1;
}
printf("%d\n",ans);
return 0;
}
poj3179
8:bzoj1465 bzoj1045: [HAOI2008] 糖果傳遞&&bzoj3293: [Cqoi2011]分金币
9:明顯x、y分開做,y就是中位數,x的話我一開始也是想要從中位數左右延伸,但是fail掉了。。正确的做法是設排完序以後,起點是a,那麼我們就是要求的sum=Σabs(a-(x[i]-i))。a就是(x[i]-i)這東西的中位數。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
LL a[11000],b[11000];
LL myabs(LL x){return x<0?-x:x;}
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&a[i],&b[i]);
sort(a+1,a+n+1);
sort(b+1,b+n+1);
for(int i=1;i<=n;i++)a[i]-=i;
sort(a+1,a+n+1);
LL sum=0;
for(int i=1;i<=n;i++)
sum+=myabs(a[i]-a[(n+1)/2]);
for(int i=1;i<=n;i++)
sum+=myabs(b[i]-b[(n+1)/2]);
printf("%lld\n",sum);
return 0;
}
poj1723

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int a[110][110],f[110][110][110];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
int ans=-2147483647;
memset(f,0,sizeof(f));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
int sum=0;
for(int k=j;k<=n;k++)
{
sum+=a[i][k];
f[i][j][k]=max(f[i-1][j][k]+sum,sum);
ans=max(ans,f[i][j][k]);
}
}
}
printf("%d\n",ans);
return 0;
}
poj1050

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<set>
using namespace std;
struct node
{
int x,y;
}a[110000],b[110000];
bool cmp(node n1,node n2)
{
if(n1.x==n2.x)return n1.y>n2.y;
return n1.x>n2.x;
}
multiset<int>s;
multiset<int>::iterator o;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
for(int i=1;i<=m;i++)scanf("%d%d",&b[i].x,&b[i].y);
sort(a+1,a+n+1,cmp);sort(b+1,b+m+1,cmp);
s.clear();
int ans=0,tp=1;long long val=0;
for(int i=1;i<=m;i++)
{
while(tp<=n&&a[tp].x>=b[i].x)s.insert(a[tp].y),tp++;
if(!s.empty())
{
if(*--s.end()>=b[i].y)
{
int k=*s.lower_bound(b[i].y);
int c=s.count(k);s.erase(k);
for(int j=1;j<c;j++)s.insert(k);
// for(o=s.begin();o!=s.end();o++)printf("%d\n",*o);
ans++;val+=b[i].x*500+2*b[i].y;
}
}
}
printf("%d %lld\n",ans,val);
}
return 0;
}
hdu4864 (因為y的範圍隻有100是以可以暴力枚舉,我沒想就搞了個set,跑得還比暴力慢-_-!)
pain and happy in the cruel world.