A 丁神去谷歌
链接:http://code.bupt.edu.cn/problem/p/416/
思路:水题呀 不说啥了 注意double的比较
code:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include<cstdio>
#include <algorithm>
#include <vector>
#define INF 1000000
using namespace std;
const int MAX_M=200;
const int MAX_N=20005;
int main()
{
int T,N,a,b,res,mida,midb;
double ff,midff;
scanf("%d",&T);
while(T--){
scanf("%d",&N);
scanf("%d%d",&mida,&midb);
midff=(double)(midb/mida);
res=1;
for(int i=2;i<=N;i++){
scanf("%d%d",&a,&b);
ff=(double)(b/a);
if(ff>midff){
midff=ff;
mida=a;
midb=b;
res=i;
}
else if(ff==midff){
if(a<mida){
mida=a;
midb=b;
res=i;
}
}
}
printf("%d\n",res);
}
return 0;
}
B 丁神又去谷歌
链接:http://code.bupt.edu.cn/problem/p/417/
思路:也是水题了 直接裸的背包 当时long long 的输出打成了“%d”wa了一次 实在是不应该
code:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include<cstdio>
#include <algorithm>
#include <vector>
#define INF 1000000
using namespace std;
const int MAX_M=200;
const int MAX_N=1015;
long long dp[MAX_N+1];
long long v[MAX_N];
int w[MAX_N];
int t,n;
long long Max(long long a,long long b)
{
if(a>b) return a;
else return b;
}
void solve()
{
for(int i=n-1;i>=0;i--){
for(int j=t;j>=0;j--){
if(j<w[i]) continue;
else dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
printf("%lld\n",dp[t]);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&t,&n);
for(int i=0;i<n;i++) scanf("%d %lld",&w[i],&v[i]);
for(int j=0;j<MAX_N;j++) dp[j]=0;
solve();
}
return 0;
}
C goblin
链接:http://code.bupt.edu.cn/problem/p/426/
思路: 递推的题目递推式具体怎么·来的还没有想清楚 待更新
(ps:一直感觉题目有问题 根据后来理解的意思应该把某个改成每个!!!!!)
code:
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <cstdio>
using namespace std;
int dp[10001][10001],n,p;
int main()
{
scanf("%d%d",&n,&p);
if (n==1) {
printf("%d\n",1 % p);
return 0;
}
dp[1][1]=1;
for (int i=2;i<=n;i++)
{
for (int j=1;j<=i;j++)
{
dp[i][j]=dp[i-1][i-j]+dp[i][j-1];
dp[i][j]%=p;
}
}
printf("%d\n",(dp[n][n]*2)%p);
return 0;
}
D 学姐逗学弟
链接:http://code.bupt.edu.cn/problem/p/427/
思路:典型的every sg,有关every sg的具体内容可以看我写的一篇hdu 3595,这道题其实比那到要简单很多,求出每个节点是先手胜还是后首胜和每个点的到最终状态的步数,关于步数和胜负关系的求解和hdu 3595一样,只是减了一维,变得更简单了,那道题如果真的整明白了,这道题真的是so easily。
hdu 3595地址:http://blog.youkuaiyun.com/u013649253/article/details/37922683
code:
//every sg
#include <iostream>
#include <cstring>
#include <cstdlib>
#include<cstdio>
#include <algorithm>
#include <vector>
#define INF 1000000000
#define eps 1e-9
using namespace std;
const int MAX_E=200100;
const int MAX_N=100005;
struct edge{int to,next;} E[MAX_E];
int head[MAX_N],si;
void add_edge(int s,int t)
{
E[si].to=t;
E[si].next=head[s];
head[s]=si++;
return ;
}
int sg[MAX_N],step[MAX_N],st[MAX_N];
int dfs(int v)
{
if(sg[v]!=-1) return sg[v];
int ma=0,mi=INF;
for(int i=head[v];i!=-1;i=E[i].next){
if(!dfs(E[i].to)){
ma=max(ma,step[E[i].to]);
sg[v]=1;
}
else mi=min(mi,step[E[i].to]);
}
if(sg[v]==1) step[v]=ma+1;
else{
if(mi==INF) step[v]=0;
else step[v]=mi+1;
sg[v]=0;
}
return sg[v];
}
int main()
{
int T,mid,n,m,ans;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
si=0,ans=0;
memset(st,0,sizeof(st));
memset(step,0,sizeof(step));
memset(sg,-1,sizeof(sg));
memset(head,-1,sizeof(head));
for(int i=2;i<=n;i++){
scanf("%d",&mid);
add_edge(mid,i);
}
for(int i=0;i<m;i++){
scanf("%d",&mid);
st[mid]++;
}
dfs(1);
for(int i=1;i<=n;i++) if(st[i]) ans=max(ans,step[i]);
if(ans%2==0) puts("So sad...");
else puts("MengMengDa!");
}
return 0;
}
E 木头人足球赛
链接:http://code.bupt.edu.cn/problem/p/425/
思路:比赛时看这个,题目上说射的很准,尼玛,我就以为那个10号队员可以射带拐弯儿的球,顿时感觉错乱了,不知道该怎么做了,结束以后听学长讲才知道只能是直线......
我的方法是先预处理,计算出10号到两个门上下沿的角度,再处理处10号到每个防守队员防守范围的切线的角度,将后者按角度的下限排序,再行开一个数组,将角度重叠的队员的数据并起来,新数据中如何存在一个角度范围能包住10号队员的射门范围的话,射门就不成功。
其中注意10队员被某个防守队员包住的情况,我处理时将这种情况下防守队员的角度设成了0~pi。
code:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define INF 10000
using namespace std;
const int MAX_N=20;
const int MAX_M=1000002;
const double Pi=acos(-1.0);
int sx,sy,p;
double uu,dd;
struct ppp
{
int x,y;
double uj,dj,mm;
} P[MAX_N],midP[MAX_N];
bool cmp(ppp A,ppp B)
{
return A.dj<B.dj;
}
double dis(int x1,int y1,int x2,int y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
void initial()
{
double midjj,midii;
uu=atan((double)sx/(sy-30));
dd=atan((double)sx/(sy-38));
if(uu<0) uu+=Pi;
if(dd<0) dd+=Pi;
for(int i=0;i<p;i++){
midjj=atan((double)(sx-P[i].x)/(sy-P[i].y));
if(dis(sx,sy,P[i].x,P[i].y)<=P[i].mm){
P[i].uj=0;
P[i].dj=Pi;
continue;
}
else midii=asin((double)P[i].mm/dis(sx,sy,P[i].x,P[i].y));
if(midjj<0) midjj+=Pi;
P[i].uj=midjj-midii;
P[i].dj=midjj+midii;
}
sort(P,P+p,cmp);
}
void solve()
{
int midp=0;
bool flag;
for(int i=0;i<p;i++){
flag=false;
for(int j=0;j<midp;j++){
if(P[i].uj<midP[j].dj){
midP[j].dj=P[i].dj;
flag=true;
break;
}
}
if(!flag){
midP[midp].uj=P[i].uj;
midP[midp++].dj=P[i].dj;
}
}
for(int i=0;i<midp;i++){
if(midP[i].uj<=uu&&midP[i].dj>=dd){
printf("Poor Mays!\n");
return ;
}
}
printf("Shoot!\n");
return ;
}
int main()
{
int T,nn;
scanf("%d",&T);
while(T--){
p=0;
scanf("%d%d",&sx,&sy);
for(int i=0;i<11;i++){
int xx,yy;
double ff;
scanf("%d%d%lf",&xx,&yy,&ff);
if(xx>sx&&dis(sx,sy,xx,yy)>ff) continue;
P[p].x=xx;
P[p].y=yy;
P[p++].mm=ff;
}
initial();
solve();
}
return 0;
}
继续加油了~~~~