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;
}