所有题目链接:http://acm.hdu.edu.cn/search.php?field=problem&key=2015ACM%2FICPC%D1%C7%D6%DE%C7%F8%B3%A4%B4%BA%D5%BE-%D6%D8%CF%D6%C8%FC%A3%A8%B8%D0%D0%BB%B6%AB%B1%B1%CA%A6%B4%F3%A3%A9&source=1&searchmode=source
F。Almost Sorted Array
判断一个数组中的数是不是几乎排好序的,几乎排好序的意思就是去掉一个后能成为排好序的数组,只要求下最长单增或单减子序列就好,
如果长度等于数组的长度或者等于数组长度-1就是一个符合的序列。
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define For(a,l,r) for(int a=l;a<r;a++)
#define F first
#define S second
using namespace std;
typedef long long LL;
const LL mod = 9973;
const LL inf=0x3f3f3f3f;
const double pi=acos(-1);
const int N=200005;//最大点数
const int M=13;// 最大边数
int T,n,m;
int a[100005];
int dp[100005];
int main()
{
#ifdef LOCALHEI
freopen("date.in","r",stdin);
freopen("date.out","w",stdout);
#endif
scanf("%d",&T);
while(T--)
//while(scanf("%d%d",&n,&m)!=EOF)
{
scanf("%d",&n);
int len=0;
scanf("%d",&a[0]);
dp[++len]=a[0];
for(int i=1;i<n;i++)
{
scanf("%d",&a[i]);
if(dp[len]<=a[i])dp[++len]=a[i];
else
{
int l=1,r=len;
while(l<=r)
{
int mid=(l+r)/2;
if(dp[mid]>a[i])r=mid-1;
else l=mid+1;
}
dp[l]=a[i];
}
}
//cout<<len<<endl;
if(len>=n-1)
{
puts("YES");
continue;
}
len=0;
dp[++len]=a[0];
for(int i=1;i<n;i++)
{
if(dp[len]>=a[i])dp[++len]=a[i];
else
{
int l=1,r=len;
while(l<=r)
{
int mid=(l+r)/2;
if(dp[mid]<a[i])r=mid-1;
else l=mid+1;
}
dp[l]=a[i];
}
}
//cout<<len<<endl;
if(len>=n-1)
{
puts("YES");
continue;
}
puts("NO");
}
return 0;
}
G。Dancing Stars on Me
给出一些点,判断能否在全用上这些点的情况下构成一个正多边形且边长为整数,易知只能构成正四边形。排序选好各对应边,判断长度是否相等就好。
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define For(a,l,r) for(int a=l;a<r;a++)
#define F first
#define S second
using namespace std;
typedef long long LL;
const LL mod = 9973;
const LL inf=0x3f3f3f3f;
const double pi=acos(-1);
const int N=200005;//最大点数
const int M=13;// 最大边数
struct node
{
int x,y;
}p[106];
bool cmp(node a,node b)
{
if(a.x==b.x)
return a.y<b.y;
else return a.x<b.x;
}
int T,n,m;
bool check()
{
sort(p,p+4,cmp);
long long s[5];
s[0]=(p[0].x-p[1].x)*(p[0].x-p[1].x)+(p[0].y-p[1].y)*(p[0].y-p[1].y);
s[1]=(p[0].x-p[2].x)*(p[0].x-p[2].x)+(p[0].y-p[2].y)*(p[0].y-p[2].y);
s[2]=(p[3].x-p[1].x)*(p[3].x-p[1].x)+(p[3].y-p[1].y)*(p[3].y-p[1].y);
s[3]=(p[2].x-p[3].x)*(p[2].x-p[3].x)+(p[2].y-p[3].y)*(p[2].y-p[3].y);
sort(s,s+4);
if(s[0]==s[3])
return true;
else
return false ;
}
int main()
{
#ifdef LOCALHEI
freopen("date.in","r",stdin);
freopen("date.out","w",stdout);
#endif
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
if(n!=4)
{
puts("NO");
continue;
}
if(check())
{
puts("YES");
}
else puts("NO");
}
return 0;
}
H - Partial Tree
n个点生成一棵树,每个节点度数不同,权值也不同,求出最大权值的树。每个节点至少要有一个度,总共有2*n-2个度,把剩下的n-2个度分到n个节点中。问题转化成将重量分别为1->n-2,价值分别为v[i](2<=i<=n-1)的物品放到体积为n-2的背包中,v[i]=f[i]-f[1],即通过改变一些度为1的节点使其达到度为i。可以用完全背包求解,需要注意的是要通过放入体积为x的 物品使其体积达到y,那么之前放到的物品一定是要能达到y-x的。
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define For(a,l,r) for(int a=l;a<r;a++)
#define F first
#define S second
using namespace std;
typedef long long LL;
const LL mod = 9973;
const LL inf=0x3f3f3f3f;
const double pi=acos(-1);
const int N=200005;//最大点数
const int M=13;// 最大边数
int T,n,m;
int f[2016];
int dp[2016];
int main()
{
#ifdef LOCALHEI
freopen("date.in","r",stdin);
freopen("date.out","w",stdout);
#endif
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=1;i<n;i++)
scanf("%d",&f[i]);
for(int i=0;i<=n;i++)
dp[i]=-inf;
dp[0]=0;
for(int i=2;i<=n-1;i++)
for(int j=(i-1);j<=n-2;j++)
if(dp[j-(i-1)]!=-inf)
dp[j]=max(dp[j-(i-1)]+f[i]-f[1],dp[j]);
printf("%d\n",f[1]*n+dp[n-2]);
}
return 0;
}
J - Chip Factory
给一些数,在这些数中选择三个互不相同的数,a、b、c,求最大的(a+b)XORc。
暴力会超时,可以用字典树优化,先把这些数存进字典树,然后两两求和判断,需要注意的是abc是不同的,所以a+b在字典树中寻值时应判断一下。两种方法:一种直接开bool数组判断,一种寻值前把a,b从树中删除。两种都贴一下。
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define For(a,l,r) for(int a=l;a<r;a++)
#define F first
#define S second
using namespace std;
typedef long long LL;
const LL mod = 9973;
const LL inf=0x3f3f3f3f;
const double pi=acos(-1);
const int N=200005;//最大点数
const int M=13;// 最大边数
int T,n,m;
int a[1005];
struct node
{
bool fla[1000];
struct node *nextt[2];
int num;
};
struct node *root;
struct node *newset()
{
struct node *p;
p=new(node);
for(int i=0;i<2;i++)
{
p->nextt[i]=NULL;
}
p->num=0;
memset(p->fla,false,sizeof(p->fla));
return p;
}
void insert(int an,int pla)
{
struct node *p;
p=root;
p->num++;
for(int i=30;i>=0;i--)
{
int tep=0;
if((an&(1<<i))!=0)
tep=1;
if(p->nextt[tep]==NULL)
{
p->nextt[tep]=newset();
}
p=p->nextt[tep];
p->fla[pla]=1;
p->num++;
}
}
int que(int an,int x,int y)
{
node *p;
p=root;
int res=an;
for(int i=30;i>=0;i--)
{
//printf("%d===\n",p->num);
int tep=0;
if((an&(1<<i))!=0)
tep=1;
if((p->nextt[tep^1]!=NULL)&&(((p->nextt[tep^1]->fla[x])&&(p->nextt[tep^1]->fla[y])&&(p->nextt[tep^1]->num>2))||((p->nextt[tep^1]->fla[x]==0)&&(p->nextt[tep^1]->fla[y])&&(p->nextt[tep^1]->num>1))||((p->nextt[tep^1]->fla[x])&&(p->nextt[tep^1]->fla[y]==0)&&(p->nextt[tep^1]->num>1))||((p->nextt[tep^1]->fla[x]==0)&&(p->nextt[tep^1]->fla[y]==0)&&(p->nextt[tep^1]->num>0))))
{
res|=(1<<i);
p=p->nextt[tep^1];
}
else if(p->nextt[tep]!=NULL)
{
res&=(~(1<<i));
p=p->nextt[tep];
// printf("i= %d %d==\n",i,res);
}
}
return res;
}
void clearr(node * root)//清空
{
for(int i=0;i<2;i++)
{
if(root->nextt[i]!=NULL)
{
clearr(root->nextt[i]);
}
}
free(root);
}
int main()
{
#ifdef LOCALHEI
freopen("date.in","r",stdin);
freopen("date.out","w",stdout);
#endif
scanf("%d",&T);
while(T--)
{
root=newset();
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
insert(a[i],i);
}
// printf("%d=====\n",root->num);
int ans=0;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
{
//printf("%d %d 9999\n",a[i],a[j]);
int aaa=que(a[i]+a[j],i,j);
//cout<<que(a[i]+a[j],i,j)<<endl;
ans=max(ans,aaa);
}
printf("%d\n",ans);
clearr(root);
}
return 0;
}
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define For(a,l,r) for(int a=l;a<r;a++)
#define F first
#define S second
using namespace std;
typedef long long LL;
const LL mod = 9973;
const LL inf=0x3f3f3f3f;
const double pi=acos(-1);
const int N=200005;//最大点数
const int M=13;// 最大边数
int T,n,m;
int a[1005];
struct node
{
struct node *nextt[2];
int num;
};
struct node *root;
struct node *newset()
{
struct node *p;
p=new(node);
for(int i=0;i<2;i++)
{
p->nextt[i]=NULL;
}
p->num=0;
return p;
}
void insert(int an)
{
struct node *p;
p=root;
p->num++;
for(int i=30;i>=0;i--)
{
int tep=0;
if((an&(1<<i))!=0)
tep=1;
if(p->nextt[tep]==NULL)
{
p->nextt[tep]=newset();
}
p=p->nextt[tep];
p->num++;
}
}
void del(int an)
{
struct node *p;
p=root;
p->num--;
for(int i=30;i>=0;i--)
{
int tep=0;
if((an&(1<<i))!=0)
tep=1;
p=p->nextt[tep];
p->num--;
}
}
int que(int an)
{
node *p;
p=root;
int res=an;
for(int i=30;i>=0;i--)
{
int tep=0;
if((an&(1<<i))!=0)
tep=1;
if(p->nextt[tep^1]!=NULL&&p->nextt[tep^1]->num>0)
{
res|=(1<<i);
p=p->nextt[tep^1];
}
else if(p->nextt[tep]!=NULL)
{
res&=(~(1<<i));
p=p->nextt[tep];
}
}
return res;
}
void clearr(node * root)//清空
{
for(int i=0;i<2;i++)
{
if(root->nextt[i]!=NULL)
{
clearr(root->nextt[i]);
}
}
free(root);
}
int main()
{
#ifdef LOCALHEI
freopen("date.in","r",stdin);
freopen("date.out","w",stdout);
#endif
scanf("%d",&T);
while(T--)
{
root=newset();
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
insert(a[i]);
}
int ans=0;
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
{
del(a[i]);
del(a[j]);
int aaa=que(a[i]+a[j]);
insert(a[i]);
insert(a[j]);
ans=max(ans,aaa);
}
printf("%d\n",ans);
clearr(root);
}
return 0;
}
L - House Building
求物体表面积。
定面积加与四周高度的差就是一个凸起的表面积,遍历一下即可。
#include <cstdio>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <string>
#include <bitset>
#include <vector>
#include <iostream>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define mem(a,b) memset(a,b,sizeof(a))
#define For(a,l,r) for(int a=l;a<r;a++)
#define F first
#define S second
using namespace std;
typedef long long LL;
const LL mod = 9973;
const LL inf=0x3f3f3f3f;
const double pi=acos(-1);
const int N=200005;//最大点数
const int M=13;// 最大边数
int T,n,m;
int a[55][55];
int main()
{
#ifdef LOCALHEI
freopen("date.in","r",stdin);
freopen("date.out","w",stdout);
#endif
scanf("%d",&T);
while(T--)
//while(scanf("%d%d",&n,&m)!=EOF)
{
memset(a,0,sizeof(a));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
long long ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(a[i][j]==0)
continue;
ans+=1;
if(a[i][j]>a[i-1][j])
ans+=(a[i][j]-a[i-1][j]);
if(a[i][j]>a[i][j-1])
ans+=(a[i][j]-a[i][j-1]);
if(a[i][j]>a[i+1][j])
ans+=(a[i][j]-a[i+1][j]);
if(a[i][j]>a[i][j+1])
ans+=(a[i][j]-a[i][j+1]);
}
printf("%lld\n",ans);
}
return 0;
}
其它的等我足够强大再说==orz