HDU 5112
水题,注意取绝对值和浮点数
#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
struct Point {
int t;
int x;
};
int cmp(Point a,Point b) {
return a.t<b.t;
}
Point p[10005];
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int T,n;
int cas=1;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
int i;
for(i=0;i<n;i++) {
scanf("%d%d",&p[i].t,&p[i].x);
}
sort(p,p+n,cmp);
double max=-1,v;
for(i=1;i<n;i++) {
v=double(1.0*abs(p[i].x-p[i-1].x)/(p[i].t-p[i-1].t*1.0));
if (v>max) max=v;
}
printf("Case #%d: %.2lf\n",cas++,max);
}
}
HDU 5122
这个题卡了好久,刚开始思路就错了。以为是之前想过的冒泡外层循环的次数,直接求最大逆序数。WA了4个小时。最后才发现题意就理解错了。
树状数组,每次移动最大数字,那它位置后的数字都前移一位。每次看以后每次在判断次数。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define lowbit(x) (x&-x)
#define maxn 1100000
using namespace std;
int n;
struct Node
{
int val;
int pos;
}node[maxn];
int a[maxn];
void update(int pos,int x)
{
while(pos<=n){
a[pos]+=x,pos+=lowbit(pos);
}
}
int getsum(int pos)
{
int res=0;
while(pos>0){
res+=a[pos],pos-=lowbit(pos);
}
return res;
}
bool cmp(const Node& a, const Node& b)
{
return a.val > b.val;
}
int main()
{
int T;
scanf("%d",&T);
int cont=0;
while (T--)
{
scanf("%d",&n);
cont++;
for (int i = 1; i <= n; ++i)
{
scanf("%d", &node[i].val);
node[i].pos = i;
}
sort(node + 1, node + n + 1, cmp);
memset(a,0,sizeof(a));
int ans=0;
for(int i=1;i<=n;i++)
{
int t=getsum(node[i].pos);
if(node[i].pos-t!=node[i].val)
ans++,update(node[i].pos,1);
}
printf("Case #%d: %d\n",cont, ans);
}
return 0;
}
HDU 5115
裸区间DP
刚开始用双向链表写了个贪心策略的。看起来真优美啊,WA
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define inf 0x3f3f3f3f
#define maxn 210
typedef long long ll;
using namespace std;
int N,M,T;
int V[maxn];
int pre[maxn],next[maxn];
struct P
{
int pos,val,give;
}p[maxn];
bool cmp(const struct P &a,const struct P &b)
{
if(a.give==b.give)
return V[ pre[a.pos] ]+V[ next[a.pos] ] < V[ pre[b.pos]]+V[pre[b.pos]];
return a.give>b.give;
}
int main()
{
scanf("%d",&T);
int cnt=0;
while (T--){
scanf("%d",&N);ll ans=0;
for(int i=1;i<=N;i++)
scanf("%d",&p[i].val),p[i].pos=i;
for(int i=1;i<=N;i++)
scanf("%d",&p[i].give),V[i]=p[i].give;
V[0]=V[N+1]=0;
p[N+1].pos=N+1;
p[N+1].val=p[N+1].give=0;
p[0].pos=p[0].val=p[0].give=0;
for(int i=1;i<=N;i++)
next[i]=i+1,pre[i]=i-1;
sort(p+1,p+N+1,cmp);
///memset(dp,0,sizeof(dp));
for(int i=1;i<=N;i++){
ans+=V[ pre[ p[i].pos ] ] +V[ next[ p[i].pos ] ] +p[i].val;
next[ pre[ p[i].pos ] ]=next[ p[i].pos ];
pre[ next[ p[i].pos ] ]=pre[ p[i].pos ];
sort(p+i+1,p+N+1,cmp);
}
printf("Case #%d: %I64d\n",++cnt, ans);
}
return 0;
}
AC:
#include <iostream>
using namespace std;
int main() {
int T;
cin >> T;
for (int cas = 1; cas <= T; cas++) {
int N;
cin >> N;
int a[202], b[202];
int dp[202][202];
for (int i = 1; i <= N; i++) {
cin >> a[i];
}
for (int i = 1; i <= N; i++) {
cin >> b[i];
}
b[0] = b[N + 1] = 0;
for (int i = 1; i <= N; i++) {
dp[i][i] = a[i] + b[i - 1] + b[i + 1];
}
for (int i = 1; i <= N ; i++) {
for (int j = 1; j + i <= N ; j++) {
dp[j][j + i] = -1;
for (int k = j; k <= j + i; k++) {
int temp;
if( k==j )
temp = dp[k+1][j+i] + a[k] + b[j+i+1] + b[j-1];
else if( k==i+j )
temp = dp[j][k-1] + a[k] + b[j-1] + b[j+i+1];
else
temp = dp[j][k-1] + dp[k+1][j + i] + a[k] + b[j-1] + b[j + i + 1];
if (dp[j][j + i] == -1 || temp < dp[j][j + i] ) {
dp[j][j + i] = temp;
}
}
}
}
cout << "Case #" << cas << ": " << dp[1][N] << endl;
}
return 0;
}
HDU 5119
裸背包,放或不放的两种情况产生结果的转移。因为数字是小于1<<20,所以遍历到此即可。
注意2^40,要用Long long 因为这个卡了1次。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int N,M,T;
long long dp[2][1<<20];
int in[50];
int main()
{
scanf("%d",&T);
int cnt=0;
while(T--){
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++)
scanf("%d",in+i);
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int i=1;i<=N;i++)
for(int j=0;j<(1<<20);j++)
dp[i%2][j^in[i]]=dp[(i-1)%2][j]+dp[(i-1)%2][j^in[i]];
long long ans=0;
for(int i=M;i<(1<<20);i++)
ans+=dp[N%2][i];
printf("Case #%d: %I64d\n",++cnt,ans);
}
}
计算几何模板题,同学备好模板哦
#include<stdio.h>
#include<math.h>
const double eps = 1e-8;
const double PI = acos(-1.0);
double min(double a,double b) {
return a<b?a:b;
}
struct Point
{
double x,y;
Point(){}
Point(double _x,double _y)
{
x = _x;y = _y;
}
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
};
double dist(Point a,Point b)
{
return sqrt((a-b)*(a-b));
}
double Area_of_overlap(Point c1,double r1,Point c2,double r2)
{
double d = dist(c1,c2);
if(r1 + r2 < d + eps)return 0;
if(d < fabs(r1 - r2) + eps)
{
double r = min(r1,r2);
return PI*r*r;
}
double x = (d*d + r1*r1 - r2*r2)/(2*d);
double t1 = acos(x / r1);
double t2 = acos((d - x)/r2);
return r1*r1*t1 + r2*r2*t2 - d*r1*sin(t1);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int T;
Point a,b;
double r,R;
double s;
scanf("%d",&T);
int cas=1;
while(T--) {
scanf("%lf%lf",&r,&R);
scanf("%lf%lf",&a.x,&a.y);
scanf("%lf%lf",&b.x,&b.y);
s=Area_of_overlap(a,R,b,R);
s-=Area_of_overlap(a,R,b,r);
s-=Area_of_overlap(a,r,b,R);
s+=Area_of_overlap(a,r,b,r);
printf("Case #%d: %.6lf\n",cas++,s);
}
return 0;
}