今天上午没事做了下昨天腾讯的比赛,发现竟然全部都会,早知道就选昨天的比赛就好了,废话不多说,下面是我的一些想法和代码。
http://acm.hdu.edu.cn/showproblem.php?pid=4520
hdu 4520:
思路:很水的题,把最终得分求出来然后一个一个比较即可。
#include <iostream> #include <string.h> #include <algorithm> #include <math.h> #include <stdio.h> using namespace std; double a[110]; double max(double a,double b) { return a>b?a:b; } double min(double a,double b) { return a<b?a:b; } int main() { freopen("dd.txt","r",stdin); int n; while(scanf("%d",&n)&&n) { int i,ans; double ma=0,mi=20,sum=0; for(i=1;i<=n;i++) { scanf("%lf",&a[i]); sum+=a[i]; ma=max(ma,a[i]); mi=min(mi,a[i]); } sum-=mi+ma; sum/=(n-2); double tmp=20; for(i=1;i<=n;i++) { if(fabs(sum-a[i])<tmp) { ans=i; tmp=fabs(sum-a[i]); } } printf("%d\n",ans); } return 0; }http://acm.hdu.edu.cn/showproblem.php?pid=4521
hdu 4521:
思路:数据结构题,我用线段树过的,我们设dp[i]为以Ai结尾满足小明序列要求的最长子序列的长度,我们可用线段树来维护这n个位置。但是只用线段树还不够,我们首先将Ai排一个序,先按Ai的大小从小到大排列,若数字相等则按位置从大到小排列。这样我们按排列后的序列依次求dp[i],然后更新线段树中对应的值。具体做法是:我们设当前我们要求的数字的位置是po,则我们只要在线段树中求区间[1,po-d-1]的最大值再加上1即为所求,为什么呢,因为经过排序后,我们在求位置dp[po]时,我们可以保证前面所求的数要么数字比当前求的小,要么位置在po之后(从而不影响dp[po]的值),所以这样做是对的。求完之后不要忘了更新线段树,将第po个数赋值为dp[po]。代码如下:
#include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #define maxn 100010 #define mid ((t[p].l+t[p].r)>>1) #define ls (p<<1) #define rs (ls|1) using namespace std; struct tree { int l,r; int max; }t[maxn<<2]; int max(int a,int b) { return a>b?a:b; } void pushup(int p) { t[p].max=max(t[ls].max,t[rs].max); } void build(int p,int l,int r) { t[p].l=l,t[p].r=r; if(l==r) { t[p].max=0; return; } build(ls,l,mid); build(rs,mid+1,r); pushup(p); } void change(int p,int x,int val) { if(t[p].l==t[p].r) { t[p].max=val; return; } if(x>mid) change(rs,x,val); else change(ls,x,val); pushup(p); } int query(int p,int l,int r) { if(l>r) return 0; if(t[p].l==l&&t[p].r==r) { return t[p].max; } if(l>mid) return query(rs,l,r); else if(r<=mid) return query(ls,l,r); else return max(query(ls,l,mid),query(rs,mid+1,r)); } struct node { int po; int num; }a[maxn]; bool cmp(node a,node b) { if(a.num==b.num) return a.po>b.po; return a.num<b.num; } int main() { // freopen("dd.txt","r",stdin); int n,d; while(scanf("%d%d",&n,&d)!=EOF) { int i; build(1,1,n); for(i=1;i<=n;i++) { scanf("%d",&a[i].num); a[i].po=i; } sort(a+1,a+n+1,cmp); int ans=0; for(i=1;i<=n;i++) { int po=a[i].po,tmp=query(1,1,po-d-1); ans=max(ans,tmp+1); change(1,po,tmp+1); } printf("%d\n",ans); } return 0; }http://acm.hdu.edu.cn/showproblem.php?pid=4522
hdu 4522:
#include <iostream> #include <string.h> #include <stdio.h> #include <queue> #include <algorithm> #define maxn 100010 using namespace std; struct edge { int to; int next; }e[2][maxn<<1]; int box[2][210],cnt[2],dist[2][210],c[2][210],inf; void init() { memset(box,-1,sizeof(box)); memset(dist,1,sizeof(dist)); memset(c,0,sizeof(dist)); inf=dist[0][0]; cnt[0]=cnt[1]=0; } void add(int from,int to,int t) { e[t][cnt[t]].to=to; e[t][cnt[t]].next=box[t][from]; box[t][from]=cnt[t]++; } char str[10010]; void makemap(int t) { int len=strlen(str),i; str[len]='+'; str[++len]='\0'; int from=0,to=0,tmp=0; for(i=0;i<len;i++) { if(str[i]=='+') { if(from!=0) { if(t) add(from,tmp,1); add(from,tmp,0); } from=tmp; tmp=0; } else tmp=10*tmp+str[i]-'0'; } } void spfa(int s,int tt) { queue<int> q; dist[tt][s]=0; c[tt][s]=1; q.push(s); while(!q.empty()) { int now=q.front(); q.pop(); c[tt][now]=0; int t,v; for(t=box[tt][now];t+1;t=e[tt][t].next) { v=e[tt][t].to; if(dist[tt][v]>dist[tt][now]+1) { dist[tt][v]=dist[tt][now]+1; if(!c[tt][v]) { c[tt][v]=1; q.push(v); } } } } } long long min(long long a,long long b) { return a<b?a:b; } int main() { //freopen("dd.txt","r",stdin); int ncase; scanf("%d",&ncase); while(ncase--) { int n,t,flag; init(); scanf("%d%d",&n,&t); while(t--) { scanf("%s%d",str,&flag); makemap(flag); } int c1,c2; scanf("%d%d",&c1,&c2); int S,T; scanf("%d%d",&S,&T); spfa(S,0); spfa(S,1); long long t1=dist[0][T],t2=dist[1][T]; if(t1==inf&&t2==inf) printf("-1\n"); else { printf("%I64d\n",min(c1*t1,c2*t2)); } } return 0; }http://acm.hdu.edu.cn/showproblem.php?pid=4523
思路:很水的一题,若n+p<m或m<3或p==0且n!=m输出NO,否则输出YES。关键还是数据范围太大,要用高精度。
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> using namespace std; #define MAX 1000 #define mod 10 #define baselen 1 struct bint { int dig[MAX]; int len; }; typedef struct bint hp; void add1(hp a,hp b,hp *c)//高精度加高精度 { int i,carry; for(i=carry=0;i<=a.len||i<=b.len||carry;i++) { if(i<=a.len) carry+=a.dig[i]; if(i<=b.len) carry+=b.dig[i]; c->dig[i]=carry%mod; carry/=mod; } c->len=i-1; } int cmp(hp a,hp b)//比较a与b的大小 若a>b 返回正数 若相等 返回0 a<b 则返回负数 { if(a.len<b.len) return -1; if(a.len>b.len) return 1; int i=a.len; while(i&&a.dig[i]==b.dig[i]) i--; return a.dig[i]-b.dig[i]; } int input(hp *a,char *data)//输入高精度正整数 { int i,j,k,len,p; len=strlen(data)-1; a->len=0; for(p=0;p<=len&&data[p]=='0';p++); while(1) { i=j=0,k=1; while(i<baselen&&len>=p) { j=j+(data[len--]-'0')*k; k*=10; i++; } a->dig[a->len++]=j; if(len<p) break; } a->len--; return 1; } hp n,m,p; char a[110],b[110],c[110]; int main() { //freopen("dd.txt","r",stdin); while(scanf("%s%s%s",a,b,c)!=EOF) { input(&n,a); input(&m,b); input(&p,c); add1(n,p,&n); int tmp=cmp(n,m); if(tmp<0) printf("NO\n"); else if(p.len==0&&p.dig[0]==0&&tmp!=0) printf("NO\n"); else { if(m.len==0&&m.dig[0]<3) printf("NO\n"); else printf("YES\n"); } } return 0; }
hdu 4524:
#include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #define maxn 1000010 using namespace std; int a[maxn]; int min(int a,int b) { return a<b?a:b; } int main() { freopen("dd.txt","r",stdin); int ncase,n,i; scanf("%d",&ncase); while(ncase--) { scanf("%d",&n); int tru=1; for(i=1;i<=n;i++) { scanf("%d",&a[i]); } for(i=1;i<n;i++) { if(a[i]>a[i+1]) { tru=0; break; } else { a[i+1]-=a[i]; } } if(!tru||a[n]) printf("I will never go out T_T\n"); else printf("yeah~ I escaped ^_^\n"); } return 0; }