ACdream原创群赛(18)题解6题

来源:互联网 发布:js控制div显示和隐藏 编辑:程序博客网 时间:2024/06/05 08:50

2014/9/6 Tonight,在ACdream上做题,发现自己的A题速度有待提高,没什么失误率,基本上做题顺序跟着AC数最多的题走,囧!

在triangle 那题,∠a =0这个情况wa 4次才想到!               -----孙权


A - KIDx's Pagination

思路:模拟论坛分页的功能,先处理左边,右边的情况对称处理即可。

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <cmath>#include <vector>#include <queue>#include <map>#include <set>using namespace std;#define LL long long#define N 50#define M 1002#define DEBUG puts("It's here!")#define INF 1<<29#define CLS(x,v) memset(x,v,sizeof(x))#define FOR(i,a,n)  for(int i=(a);i<=(n);++i)int n,cur,d;string s;string convert(int i){    char buf[5];    sprintf(buf, "%d", i);    string b = buf;    return b;}void  solvel(){    int i=cur-1,cnt=1;    if(cur==1)    {       s="[<<]"+s;    }    else    {        while(i>=1&&cnt<=d)        {            s="("+convert(i)+")"+s;            i--;            cnt++;        }        if(i>=1)s="[...]"+s;        s="(<<)"+s;    }}void  solver(){    int i=cur+1,cnt=1;    if(cur==n)    {       s=s+"[>>]";    }    else    {        while(i<=n&&cnt<=d)        {            s=s+"("+convert(i)+")";            i++;            cnt++;        }        if(i<=n)s=s+"[...]";        s=s+"(>>)";    }}int main(){    int cnt=1;    while(~scanf("%d%d%d",&n,&cur,&d))    {        s="["+convert(cur)+"]";        solvel();        solver();        printf("Case #%d: %s\n",cnt++,s.c_str());    }    return 0;}

B - Points In Cuboid

C - Transformers' Mission

D - Heros and Swords

思路:先将power 和 weight 排序,对于每个人i,他能拿的武器数量就是weight[ ] <=power[i],weight的个数,乘起来就行了,如果发现某个人没有武器可拿,直接返回0 即可。

效率:O(n*log(n)+ O(n))

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <cmath>#include <vector>#include <queue>#include <map>#include <set>using namespace std;#define LL long long#define N 50#define M 100002#define DEBUG puts("It's here!")#define INF 1<<29#define CLS(x,v) memset(x,v,sizeof(x))#define FOR(i,a,n)  for(int i=(a);i<=(n);++i)LL mod=1000000007;int n;int w[M],power[M];LL solve(){    int j=0,cnt=0;    LL ans=1;    for(int i=0;i<n;i++)    {        while(j<n&&power[i]>=w[j])        {            cnt++;            j++;        }        if(cnt==0)return (LL)0;        ans=ans*cnt;if(ans>=mod)ans%=mod;        cnt--;    }    return ans;}int main(){    int T;    scanf("%d",&T);    for(int i=1;i<=T;i++)    {        scanf("%d",&n);        for(int i=0;i<n;i++)            scanf("%d",&w[i]);        for(int i=0;i<n;i++)            scanf("%d",&power[i]);         sort(w,w+n);         sort(power,power+n);         printf("Case #%d: %lld\n",i,solve());    }    return 0;}

E - Jump! Jump! Jump!

F - SuSu's Power

G - Integer in C++

思路:正数和负数分别处理,从表示范围小的开始比较即可,直接比较string,<= 是说明可以表示。

string s;string base[3]={"-32768","-2147483648","-9223372036854775808"};string base2[3]={"32767","2147483647","9223372036854775807"};int l[3]={6,11,20};int r[3]={5,10,19};string ans[4]={"short","int","long long","It is too big!"};int compare(string a,string b,int len){ // <= 返回1    for(int i=0;i<len;i++)        if(a[i]!=b[i])        return a[i]<b[i];    return 1;}int solve(string* base,int* a){    int n=s.length();    if(n<a[0])return 0;    else if(n==a[0]){        if(compare(s,base[0],n))return 0;        else return 1;    }else if(n<a[1])    {        return 1;    }else if(n==a[1])    {        if(compare(s,base[1],n))return 1;        else return 2;    }    else if(n<a[2])    {        return 2;    }else if(n==a[2])    {        if(compare(s,base[2],n))return 2;        else return 3;    }else    {        return 3;    }}int main(){    ios::sync_with_stdio(false);    int ret;    while(cin>>s)    {        if(s[0]=='-')ret=solve(base,l);        else ret=solve(base2,r);        cout<<ans[ret]<<endl;    }    return 0;}

H - KIDx's Triangle

思路:求边长假设底边长度为L,根据正弦定理,求出相应的边,根据余弦定理求出角度的余弦,

注意:当角a==0时,结果为0(wa了3次) 

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <cmath>#include <vector>#include <queue>#include <map>#include <set>using namespace std;#define LL long long#define N 50#define M 1002#define DEBUG puts("It's here!")#define INF 1<<29#define CLS(x,v) memset(x,v,sizeof(x))#define FOR(i,a,n)  for(int i=(a);i<=(n);++i)double a,b,c,d,A,B,D,E;double PI=acos(-1.0);double hudu=180.0/PI;int main(){    double l1,l2,l3,l4,l5;    double l=1.0;   // printf("%.3lf",(double)sin(1.5));  // printf("aaaa=%.6lf\n",cos(20.0/hudu));  // printf("aaaa=%.2lf\n",180/PI*acos(0.939693));    while(~scanf("%lf%lf%lf%lf",&a,&b,&c,&d))    {        if(a==0){printf("0.00\n");continue;}        A=(a+b)/hudu;        B=(c+d)/hudu;        D=(180.0-a-b-c)/hudu;        E=(180.0-b-c-d)/hudu;        a=a/hudu;        b=b/hudu;        c=c/hudu;        d=d/hudu;        l2=l*sin(B)/sin(E);        l3=l*sin(c)/sin(D);        l4=l*sin(A)/sin(D);        l5=l*sin(b)/sin(E);        double doublel1=l4*l4+l5*l5-2*l4*l5*cos(d);        l1=sqrt(1.0*doublel1);        double cosarp= (l1*l1+l2*l2-l3*l3)/(2*l1*l2);        double ans=hudu*acos(cosarp);      //  printf("--->%.3lf-->",cosarp);        printf("%.2lf\n",ans);    }    return 0;}

I - Integration of Polynomial

思路:GCD求最大公约数

int n;int k[1002],e[1002];int GCD(int a,int b){    return b==0?a:GCD(b,a%b);}void solve(){    int flag=1;    int a,b;    for(int i=0; i<n; i++)    {        a=k[i];        b=e[i]+1;        int p;        if(a<0)p=GCD(-a,b);        else p=GCD(a,b);        a/=p;        b/=p;        if(b==1)        {            if(flag){printf("%d",a);flag=0;}            else printf(" %d",a);        }        else        {            if(flag){printf("%d/%d",a,b);flag=0;}            else printf(" %d/%d",a,b);        }        printf(" %d",e[i]+1);    }    printf("\n");}int main(){    while(~scanf("%d",&n))    {        for(int i=0; i<n; i++)        {            scanf("%d%d",&k[i],&e[i]);        }        solve();    }    return 0;}

J - Disappeared Block

题意:这是真是一道好题!题意:有n个高度分别为hi(0<hi<10^9) 的城市在一条水平线上,每隔一分钟海水会淹没一层,t =0,海水高度为0,多次询问,问你k 分钟后,有多少个连通块(城市连在一起算一个)?

思路:逆向思维,终有一天,海水会淹没所有城市(有点像诺亚方舟),然后每隔1分钟海水会消退一层,在t 时刻,对于每座楼i,hi>t才会在水面上。只要看城市i左右城市的状态即可。

效率:O(n+m)

如果询问不是按照递增序列给出,得先将查询 排一下序,做完,再按照id 排一下序输出即可!

输入达10^6,加输入优化,发现速度快了400ms!!

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <stack>#include <cmath>#include <vector>#include <queue>#include <map>#include <set>using namespace std;#define LL long long#define N 50#define M 1000006#define DEBUG puts("It's here!")#define INF 1<<29#define CLS(x,v) memset(x,v,sizeof(x)) struct build{  int h,id;  bool operator <(const build &b)const{    return h<b.h;  }}a;int n,query[M];bool vis[M];priority_queue<build> Q;int main(){    int T,m;    scanf("%d",&T);    for(int k=1;k<=T;k++)    {        while(!Q.empty())Q.pop();        scanf("%d%d",&n,&m);        for(int i=1;i<=n;i++)        {            scanf("%d",&a.h);            a.id=i;            Q.push(a);        }        for(int i=1;i<=m;i++)//m个查询时间,由小到大            scanf("%d",&query[i]);        int cnt=0;        CLS(vis,0);        for(int i=m;i>0;i--)        {            while(!Q.empty()&&Q.top().h>query[i])//将所有高出水面的楼全部处理掉!            {                int id=Q.top().id;                Q.pop();                if(vis[id-1]&&vis[id+1])cnt--;                else if(!vis[id-1]&&!vis[id+1])cnt++;                vis[id]=1;            }            query[i]=cnt;        }        printf("Case #%d:",k);        for(int i=1;i<=m;i++)            printf(" %d",query[i]);        putchar('\n');    }    return 0;}




0 0