【URAL 刷题记】URAL 1600 ~ URAL 1607
2016-02-09 14:47
489 查看
URAL 1600
URAL 1601
URAL 1602
URAL 1603
URAL 1604
URAL 1605
URAL 1606
URAL 1607
/* 题意: 给三维空间中n个点, 且每个点有平均飞行的向量. 问是否存在一个时间, 2个东西距离<=d 暴力枚举点对, 然后三分判最低点是不是小于等于d.如果是的话, 在其左侧二分寻找恰好距离为d的时间. (我是直接取一个平面以后看成射线与圆的交点问题。。。) */ #include<cstdio> #include<cmath> double eps=1e-8; int dcmp(const double& x){ return fabs(x)<eps ? 0 : (x<0 ? -1 : 1); } struct Point3{ double x,y,z; Point3(){} Point3(double x,double y,double z):x(x),y(y),z(z){} bool operator ==(const Point3& B)const{ return dcmp(x-B.x)==0 && dcmp(y-B.y)==0 && dcmp(z-B.z)==0; } void read(){ double x,y,z; scanf("%lf%lf%lf",&x,&y,&z); this->x=x, this->y=y, this->z=z; } }; Point3 operator +(const Point3& A,const Point3& B){ return Point3(A.x+B.x,A.y+B.y,A.z+B.z); } Point3 operator -(const Point3& A,const Point3& B){ return Point3(A.x-B.x,A.y-B.y,A.z-B.z); } Point3 operator *(const Point3& A,const double& b){ return Point3(A.x*b,A.y*b,A.z*b); } Point3 operator /(const Point3& A,const double& b){ return Point3(A.x/b,A.y/b,A.z/b); } double Dot(const Point3& A,const Point3& B){ return A.x*B.x+A.y*B.y+A.z*B.z; } double Length(const Point3& A){ return sqrt(Dot(A,A)); } Point3 Cross(const Point3& A,const Point3& B){ return Point3(A.y*B.z-A.z*B.y, A.z*B.x-A.x*B.z, A.x*B.y-A.y*B.x); } double DistanceToLine(const Point3& P, const Point3& A,const Point3& B){ Point3 v1=B-A, v2=P-A; return Length(Cross(v1,v2))/Length(v1); } double DistanceToSegment(const Point3& P, const Point3& A,const Point3& B){ if(A==B) return Length(P-A); Point3 v1=B-A, v2=P-A, v3=P-B; if(dcmp(Dot(v1,v2))<0) return Length(v2); else if(dcmp(Dot(v1,v3))>0) return Length(v3); else return Length(Cross(v1,v2))/Length(v1); } double DistanceToHalfline(const Point3& P, const Point3& A,const Point3& B){ if(A==B) return Length(P-A); Point3 v1=B-A, v2=P-A; if(dcmp(Dot(v1,v2))<0) return Length(v2); else return Length(Cross(v1,v2))/Length(v1); } const int maxn=510; int n; double D; Point3 A[maxn],v[maxn]; double mit; int mix,miy; double sqr(double x){ return x*x; } void calc(){ for(int i=1;i<=n;++i){ for(int j=1;j<=n;++j)if(j!=i){ if(Length(A[j]-A[i])<D){ mit=0,mix=i,miy=j; return; } double x=DistanceToHalfline(A[i],A[j],A[j]+(v[j]-v[i])); if(dcmp(x-D)<=0){ double d1=sqrt(sqr(Length(A[j]-A[i]))-sqr(x)), d2=sqrt(sqr(D)-sqr(x)); double t=fabs((d2-d1)/Length(v[j]-v[i])); if(dcmp(t-mit)<0){ mit=t; mix=i, miy=j; } } } } } void solve(){ scanf("%d%lf",&n,&D); for(int i=1;i<=n;++i){ A[i].read(); v[i].read(); } mit=1e30; mix=-1; calc(); if(mix==-1) puts("OK"); else printf("ALARM!\n%.3lf %d %d\n",mit,mix,miy); } int main(){ // freopen("in.txt","r",stdin); solve(); // for(;;); return 0; }
URAL 1601
/* 简单模拟题,将非句子开头的大写字母转化成小写即可,注意行首字母不一定大写 */ #include<algorithm> #include<cstdio> #include<cstring> #include<cctype> const int maxn=10010; int n; char s[maxn]; void solve(){ int fst=1; while (gets(s)){ n=strlen(s); for(int i=0;i<n;++i){ if(isalpha(s[i])){ if(fst){ putchar(toupper(s[i])); fst=0; }else putchar(tolower(s[i])); }else putchar(s[i]); if(s[i]=='.' || s[i]=='!' || s[i]=='?') fst=1; } putchar('\n'); } } int main(){ // freopen("in.txt","r",stdin); solve(); // for(;;); return 0; }
URAL 1602
/* C题:一个人坐电梯,一开始电梯在k层,电梯要先下到1层,人可以从n层先下到x层再叫电梯。。。 枚举人先走到哪层即可。。。 (注意,人按电梯,电梯才会上楼。。) */ #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const double eps=1e-8; double dcmp(double x){ return fabs(x)<eps ? 0 : (x < 0 ? -1 : 1); } int n,k; double u,v; void solve(){ scanf("%d%d%lf%lf",&n,&k,&u,&v); double mit=(n-1)*u; int mix=1; for(int x=n;x>=2;--x){ double t1=(n-x)*u, t2=(k-1)*v+15; double tm=max(t1,t2)+(x-1)*v+5+(x-1)*v; if(dcmp(tm-mit)<0){ mit=tm; mix=x; } } printf("%d\n",mix); } int main(){ // freopen("in.txt","r",stdin); solve(); // for(;;); return 0; }
URAL 1603
/* 题意:给4*4的填字格,组成单词的方法是:从一个格子开始向四周走,然后不能走到同一个格子,给m个单词问能否用这个方法组成。 题解:直接把所有可能的单词全做出来,判断即可 */ #include<algorithm> #include<cstdio> #include<cstring> #include<string> #include<iostream> using namespace std; const int maxn=10; string res[100000]; int resN; const int dxy[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; char mp[maxn][maxn]; bool check(int x,int y){ return 0<=x&&x<4&&0<=y&&y<4; } bool vis[maxn][maxn]; void dfs(int x,int y,string now){ vis[x][y]=1; res[resN++]=now; for(int d=0;d<4;++d){ int X=x+dxy[d][0], Y=y+dxy[d][1]; if(check(X,Y)&&!vis[X][Y]){ dfs(X,Y,now+mp[X][Y]); } } vis[x][y]=0; } char now[maxn*maxn]; void solve(){ for(int i=0;i<4;++i) scanf("%s",mp[i]); memset(vis,0,sizeof vis); for(int i=0;i<4;++i) for(int j=0;j<4;++j) dfs(i,j,string("") + mp[i][j]); sort(res,res+resN); int m;scanf("%d",&m); while(m--){ scanf("%s",now); string nows=now; printf("%s: ",now); // cout << *lower_bound(res,res+resN,nows) << endl; if(nows==*lower_bound(res,res+resN,nows)) puts("YES"); else puts("NO"); } } int main(){ // freopen("in.txt","r",stdin); solve(); // for(;;); return 0; }
URAL 1604
/* 是给你n个数,有k种。要求把它们排成一列,使得相邻两个相同的情况尽可能少。 把出现次数最多的和次多的依次放就行了,搞个堆。 */ #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<queue> using namespace std; typedef pair<int,int> P; priority_queue<P> pq; int k; void solve(){ scanf("%d",&k); for(int i=1;i<=k;++i){ int x;scanf("%d",&x); pq.push(P(x,i)); } while(!pq.empty()){ P x=pq.top(); pq.pop(); if(pq.empty()){ for(int i=0;i<x.first;++i) printf("%d ",x.second); break; } P y=pq.top(); pq.pop(); printf("%d %d ",x.second,y.second); if(x.first>1) pq.push(P(x.first-1,x.second)); if(y.first>1) pq.push(P(y.first-1,y.second)); } putchar('\n'); } int main(){ // freopen("in.txt","r",stdin); solve(); // for(;;); return 0; }
URAL 1605
/* 数列是逼近2/3的数列,所以xn是 k/2^n (0<=k<=2^n)里面最接近2/3的,然后奇数项小于2/3,偶数项大于2/3 通项公式 floor((2^i) * 2 / 3) + (i%2) 暴力求出这个数即可 c++的做法的话,通项公式 x_n = 2/3 + (1/3)/(2^(n-1)) n is odd x_n = 2/3 - (1/3)/(2^(n-1)) n is even 观察后面一部分,设d=(1/3)/(2^(n-1))=0.00..0XXX..XX 可以知道,小数点后0的个数是k=floor[Log10(3)+(n-1)*Log10(2)] 那么, 如果n is odd,如果d>0.00..0333..3(0的个数=k),那么答案输出k-1,否则输出k 如果n is even,如果d>0.00..0666..6(0的个数=k),那么答案输出k-1,否则输出k */ #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<iostream> using namespace std; typedef long double LD; int n; void solve(){ scanf("%d",&n); // if(n==100000) { puts("30102"); return; } LD t=log10(3)+(n-1)*log10(2); int k=(int)t; LD lgD=-t,lgA=(n&1) ? (-log10(3)-k) : (log10(2)-log10(3)-k); // cout << k << ' ' << (double)pow(10,lgA) << ' ' << (double)pow(10,lgD) << ' ' << (lgA>lgD) << endl; // printf("%d %d\n",pow(10,lgA)<=pow(10,lgD), lgA<=lgD); printf("%d\n",k-(lgA<=lgD)); } int main(){ // freopen("in.txt","r",stdin); /* double a=0,b=1,c; for(int t=0;t<10;++t){ c=(a+b)/2; printf("%d %.10lf\n",t+2,c); a=b;b=c; } */ solve(); // for(;;); return 0; }
URAL 1606
/* 滑雪,从上到下,然后轨迹要是折线,拐点必须在桩上,而且每次都得转向(一次往左一次往右),然后最大化碰到的桩数 直接维护<x,>x数的最大值即可。 */ #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<functional> using namespace std; typedef pair<int,int> P; const int maxn=100010; int upd(int& a,int b){ return a<b ? a=b,1 : 0; } int Tl[maxn],Tr[maxn],TN; int Til[maxn], Tir[maxn]; void add(int* T,int* Ti,int x,int v,int i){ for(;x<=TN;x+=x&-x) if(upd(T[x],v)) Ti[x]=i; } P sum(int* T,int* Ti,int x){ int v=-1,vi; for(;x;x-=x&-x) if(upd(v,T[x])) vi=Ti[x]; return P(v,vi); } int g[maxn][2]; pair<P,int> a[maxn]; int n; void print(int i,int j){ if(g[i][j]) print(g[i][j],j^1); printf("%d ",a[i].second); } void solve(){ scanf("%d",&n); for(int i=1;i<=n;++i){ int x,y;scanf("%d%d",&x,&y); a[i]=make_pair(P(y,x),i); } sort(a+1,a+1+n,greater< pair<P,int> >()); TN=100000; memset(Tl,0,sizeof Tl); memset(Tr,0,sizeof Tr); memset(Til,0,sizeof Til); memset(Tir,0,sizeof Tir); int res=-1; P resi; for(int i=1;i<=n;++i){ int x=a[i].first.second, fl,fr; P p; p=sum(Tr,Tir,TN-(x+1)+1); fl=p.first+1, g[i][0]=p.second; p=sum(Tl,Til,x-1); fr=p.first+1, g[i][1]=p.second; // printf("%d %d\n",fl,fr); add(Tl,Til,x,fl,i); add(Tr,Tir,TN-x+1,fr,i); if(upd(res,fl)) resi=P(i,0); if(upd(res,fr)) resi=P(i,1); } printf("%d\n",res); print(resi.first, resi.second); putchar('\n'); } int main(){ // freopen("in.txt","r",stdin); solve(); // for(;;); return 0; }
URAL 1607
/* 题意: 乘客坐计程车, 乘客一开始出价a, 司机要价c, 两人没达成一致的话 乘客加b, 司机减d 问什么时候两人成交 模拟即可 注意特判 1. 如果一开始出价就满足,直接输出 2. 如果某次乘客加价超过司机价格,此时乘客直接按司机价格输出 3. 如果某次司机减价低于乘客价格,此时司机直接按乘客价格输出 */ #include<algorithm> #include<cstdio> #include<cstring> using namespace std; int a,b,c,d; void solve(){ scanf("%d%d%d%d",&a,&b,&c,&d); for(;a<c;){ if(a+b>=c){ a=c; break; } a+=b; if(c-d<=a)break; c-=d; } printf("%d\n",a); } int main(){ // freopen("in.txt","r",stdin); solve(); // for(;;); return 0; }
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1002
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points