大力施工中...(9/13)
A.BBP Formula(hdu6217)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6217
开始不太会啊?后来看了看dalao的博客,发现,这个给的公式很奇妙啊,计算第n位小数,首先将式子乘上16^(n-1),然后计算小数部分就行了,因为我们只考虑小数部分,所以可以在计算的过程中,将分子对分母取模,所得到的小数部分是相同的,然后将小数部分乘16就可以得到16进制下的取值了。而且看起来精度没有什么问题。
代码:
#include
using namespace std;
typedef long long ll;
ll qpow(ll a,ll b,ll MOD)
{
ll ret=1;
while(b)
{
if(b&1)
ret=ret*a%MOD;
a=a*a%MOD;
b>>=1;
}
return ret;
}
double BBP(int n,double a,double b)
{
double ret=0;
for(int k=0;k<=n;k++)
{
ret+=qpow(16,n-k,8*k+b)*1.0/(k*8.0+b);
}
return ret*a;
}
double cal(int n)
{
return BBP(n,4,1)+BBP(n,-2,4)+BBP(n,-1,5)+BBP(n,-1,6);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
for(int _=1;_<=T;_++)
{
int n;
scanf("%d",&n);
n--;
double r=cal(n);
r=r-(ll)r;
if(r<0)
r+=1.0;
r*=16;
int res=r;
printf("Case #%d: %d %c\n",_,n+1,res>9?res-10+'A':res+'0');
}
return 0;
}
C.Empty Convex Polygons(hdu6219)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6219
最大空凸包板题,首先枚举一个点作为凸包的最下的点,然后进行极角排序,dp[i][j]表示最后一条边是点i到j缩围成的最大空凸包的面积是多少,进行转移即可,每次都要判断,是否有点在凸包内,转移时要判断两条线的夹角关系,时间复杂度O(n^4),好象有n^3的做法啊?有空学一学。
代码:
#include
using namespace std;
const int MAXN=55;
const double eps=1e-6;
int dp[MAXN][MAXN];
int n;
struct Point
{
int x,y,dis;
double angel;
double operator ^ (const Point &b)const//叉积
{
return x*b.y-y*b.x;
}
bool operator == (const Point &b)const
{
return x==b.x&&y==b.y;
}
Point operator - (const Point &b)const
{
Point ret;
ret.x=x-b.x;
ret.y=y-b.y;
return ret;
}
}p[MAXN],st[MAXN],p0;
int sgn(double x)
{
if(fabs(x)0&&res[1]>=0&&res[2]>0)
{
if(res[1]==0)
{
int dis1=dis(b,c);
int dis2=dis(P,c);
if(dis1>dis2)
return 1;
}
return 2;
}
return 0;
}
int getans()
{
int s,ret=0;
sort(st+1,st+1+n,cmp);
for(int i=1;i<=n;i++)
{
if(st[i]==p0)
{
s=i;
break;
}
}
memset(dp,-1,sizeof(dp));
for(int i=s+1;i<=n;i++)
{
dp[s][i]=0;
}
for(int i=s+1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
//dp[i][j],最后一条线是(i,j)
int flag=0;
for(int k=1;k<=n;k++)
{
int f=judge(st[k],st[j],st[i],st[s]);
flag=max(flag,f);
}
if(flag==1)
dp[i][j]=max(dp[i][j],dp[s][i]+area(st[i]-st[s],st[j]-st[s]));
if(flag)
continue;
Point now=st[j]-st[i];
for(int k=1;k<=n;k++)
{
if(dp[k][i]!=-1)
{
Point tmp=st[i]-st[k];
int res=tmp^now;
if(res>=0)
dp[i][j]=max(dp[i][j],dp[k][i]+area(st[i]-st[s],st[j]-st[s]));
}
}
ret=max(ret,dp[i][j]);
}
}
return ret;
}
void solve()
{
int ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
}
for(int i=1;i<=n;i++)
{
p0=p[i];
for(int j=1;j<=n;j++)
{
st[j]=p[j];
st[j].angel=atan2(st[j].y-p0.y,st[j].x-p0.x);
st[j].dis=dis(st[j],p0);
}
ans=max(ans,getans());
}
printf("%d",ans>>1);
printf(".%d\n",(ans&1)*5);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
solve();
}
return 0;
}
F.Heron and His Triangle(hdu6222)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6222
打个表找规律,发现dp[i]=4*dp[i-1]-dp[i-2],dp[0]=2,dp[1]=4,然后java大数就好了。
代码:
import java.math.*;
import java.util.*;
import java.io.*;
public class Main
{
static public Vector init()
{
BigInteger a,b,c,lim,four;
a=new BigInteger("2");
b=new BigInteger("4");
four=new BigInteger("4");
lim=new BigInteger("1000000000000000000000000000000");
Vector v=new Vector();
c=b.multiply(four).subtract(a);
v.add(b);
v.add(c);
while(c.compareTo(lim)<=0)
{
a=b;
b=c;
c=b.multiply(four).subtract(a);
v.add(c);
}
return v;
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
Scanner cin=new Scanner(new BufferedInputStream(System.in));
Vector v=init();
int T=cin.nextInt();
while(T>0)
{
T--;
BigInteger x=cin.nextBigInteger();
for(int i=0;i
G.Infinite Fraction Path(hdu6223)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6223
我好像是个辣鸡啊???
排序排反了debug了一个小时???
这个题怎么爆爆爆就过了啊????
直接按层搜索,随便剪剪就行了
代码:
#include
using namespace std;
typedef long long ll;
const int MAXN=150000+5;
int nxt[MAXN],a[MAXN],ans[MAXN],vis[MAXN],mx;
char s[MAXN];
struct node
{
int val,dp;
node(int _val=0,int _dp=0):val(_val),dp(_dp){}
bool operator<(const node &o)const
{
if(dp==o.dp)
return a[val]o.dp;
}
};
void init(int _n)
{
mx=0;
for(int i=0;i<_n;i++)
{
nxt[i]=(1LL*i*i+1LL)%(ll)_n;
a[i]=s[i]-'0';
mx=max(a[i],mx);
ans[i]=0;vis[i]=-1;
}
}
void bfs(int n)
{
priority_queue Q;
ans[0]=mx;
for(int i=0;i=ans[nx.dp])
{
ans[nx.dp]=a[nx.val];
Q.push(nx);
}
}
for(int i=0;i
H.Legends of the Three Kingdoms(hdu6224)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6224
直接搜索就行,照着叉姐的代码写的
代码:
#include
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair pii;
typedef tuple State;
const double eps=1e-12;
inline int dcmp(double x)
{
return x<-eps?-1:x>eps;
}
State dp[40][40][40][40][4];
template
State combine(vector &vec)
{
if(vec.empty()) return State(0,0,0);
double mx=-1;
for(const State &s:vec)
{
mx=max(mx,get(s));
}
int cnt=0;
State ret;
for(const State &s:vec)
{
if(dcmp(get(s)-mx)==0)
{
ret=State(get<0>(ret)+get<0>(s),
get<1>(ret)+get<1>(s),
get<2>(ret)+get<2>(s));
cnt++;
}
}
assert(cnt>0);
return State(get<0>(ret)/cnt,
get<1>(ret)/cnt,
get<2>(ret)/cnt);
}
void init()
{
for(int A=0;A<40;A++)
{
for(int B=0;B<40;B++)
{
for(int C=0;C<40;C++)
{
for(int D=0;D<40;D++)
{
for(int at=0,count=0;count<4;count++,at=(at+3)%4)
{
if(A==0)
{
if(B==0&&C==0&&D!=0)
{
dp[A][B][C][D][at]=State(0,0,1);
}
else
{
dp[A][B][C][D][at]=State(0,1,0);
}
continue;
}
if(B==0&&D==0)
{
dp[A][B][C][D][at]=State(1,0,0);
continue;
}
if((A==0&&at==0)||
(B==0&&at==1)||
(C==0&&at==2)||
(D==0&&at==3))
{
dp[A][B][C][D][at]=dp[A][B][C][D][(at+1)%4];
continue;
}
vector vec;
if(at==0||at==2)
{
if(B) vec.emplace_back(dp[A][B-1][C][D][at+1]);
if(D) vec.emplace_back(dp[A][B][C][D-1][at+1]);
dp[A][B][C][D][at]=combine<0>(vec);
}
else if(at==1)
{
if(A) vec.emplace_back(dp[A-1][B][C][D][at+1]);
if(C) vec.emplace_back(dp[A][B][C-1][D][at+1]);
if(D) vec.emplace_back(dp[A][B][C][D-1][at+1]);
dp[A][B][C][D][at]=combine<1>(vec);
}
else if(at==3)
{
if(A) vec.emplace_back(dp[A-1][B][C][D][0]);
if(B) vec.emplace_back(dp[A][B-1][C][D][0]);
if(C) vec.emplace_back(dp[A][B][C-1][D][0]);
dp[A][B][C][D][at]=combine<2>(vec);
}
}
}
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
init();
scanf("%d",&T);
while(T--)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&c,&b,&d);
const State &res=dp[a][b][c][d][0];
printf("%.6lf %.6lf %.6lf\n",
get<0>(res),
get<1>(res),
get<2>(res));
}
return 0;
}
I.Little Boxes(hdu6225)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6225
水题,直接上__int128就好了
代码:
#include
using namespace std;
typedef unsigned long long ll;
void print(__int128 x)
{
if(!x)
{
puts("0");
return ;
}
string ret="";
while(x)
{
ret+=x%10+'0';
x/=10;
}
reverse(ret.begin(),ret.end());
cout<
K.Rabbits(hdu6227)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6227
签到题,从直接模拟第1个向第n个跳,或者第n个向第1个跳这两种情况,然后取最大值即可
代码:
#include
using namespace std;
const int MAXN=505;
int a[MAXN];
void solve()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int ans=0,mx;
mx=0;
for(int i=2;i
L.Tree(hdu6228)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6228
对于每一条边,只要两边同时有k个以上的点就行,随便找一个度为1的点为根,然后dfs子树内外的点数就好了
代码:
#include
using namespace std;
const int MAXN=2e5+5;
int sz[MAXN],head[MAXN],tot,root,ans,n,k;
struct edge
{
int to,nxt;
}E[MAXN*2];
void addedge(int u,int v)
{
E[tot].to=v;E[tot].nxt=head[u];head[u]=tot++;
E[tot].to=u;E[tot].nxt=head[v];head[v]=tot++;
}
void init(int _n)
{
tot=0;root=0;ans=0;
for(int i=1;i<=_n;i++)
{
head[i]=-1;
sz[i]=0;
}
}
void dfsroot(int now,int fa)
{
bool flag=false;
for(int i=head[now];~i;i=E[i].nxt)
{
int v=E[i].to;
if(v==fa)
continue;
flag=true;
dfsroot(v,now);
}
if(!flag)
root=now;
}
void dfssz(int now,int fa)
{
sz[now]=1;
for(int i=head[now];~i;i=E[i].nxt)
{
int v=E[i].to;
if(v==fa)
continue;
dfssz(v,now);
sz[now]+=sz[v];
}
}
void dfsans(int now,int fa)
{
if(n-sz[now]>=k&&sz[now]>=k)
ans++;
for(int i=head[now];~i;i=E[i].nxt)
{
int v=E[i].to;
if(v==fa)
continue;
dfsans(v,now);
}
}
void solve()
{
scanf("%d%d",&n,&k);
init(n);
for(int i=1;i
M.Wandering Robots(hdu6229)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6229
wa,又是找规律题,最后发现,等于右下部分的所有的度的和比整张图的度的和,因为题目保证一定联通,所以,直接开一个map标记某个点有没有障碍,一个障碍一个障碍加进去即可。
代码:
#include
#define mp make_pair
#define xx first
#define yy second
using namespace std;
typedef pair pii;
map sv;
int tot,up,n,m;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
bool exist(int x,int y)
{
if(x<0||x>n-1||y<0||y>n-1)
return true;
if(sv.find(mp(x,y))!=sv.end())
return true;
return false;
}
int getin(int x,int y)
{
int ret=5;
for(int i=0;i<4;i++)
{
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(exist(tx,ty))
ret--;
}
return ret;
}
void handle(int x,int y)
{
int sub=getin(x,y);
tot-=sub;
if(x+y>=n-1)
up-=sub;
for(int i=0;i<4;i++)
{
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(!exist(tx,ty))
{
tot--;
if(tx+ty>=n-1)
up--;
}
}
sv[mp(x,y)]=1;
}
void solve()
{
sv.clear();
scanf("%d%d",&n,&m);
tot=n*n*5-n*4;
up=5*n*(n+1)/2-n*2-2;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
handle(x,y);
}
int g=__gcd(up,tot);
up/=g;tot/=g;
printf("%d/%d\n",up,tot);
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
scanf("%d",&T);
for(int _=1;_<=T;_++)
{
printf("Case #%d: ",_);
solve();
}
return 0;
}