[TIOJ] 1777. 房屋運動(HOU12)
題目連結:http://tioj.infor.org/problems/1777
先說本題需要寫個大數,要有減法運算跟比大小的運算,因為我有點懶(?所以就抄了日月掛長大大的模板 正題:其實不難發現兩人相撞後其實就是兩然交換往哪邊滾動的工作,其他位置什麼的都沒變,而題目也只要求最少需要多久,沒問說誰是最後一個完成的,所以我們其實就直接找離終點最遠的那位就好了,不過值得注意的是如果他兩個方向都可以就要選比較小的那個,大概就醬吧
先說本題需要寫個大數,要有減法運算跟比大小的運算,因為我有點懶(?所以就抄了日月掛長大大的模板 正題:其實不難發現兩人相撞後其實就是兩然交換往哪邊滾動的工作,其他位置什麼的都沒變,而題目也只要求最少需要多久,沒問說誰是最後一個完成的,所以我們其實就直接找離終點最遠的那位就好了,不過值得注意的是如果他兩個方向都可以就要選比較小的那個,大概就醬吧
#include <bits/stdc++.h>
using namespace std;
#ifndef SUN_MOON_BIG_INT
#define SUN_MOON_BIG_INT
#define SM_BASE 1000000000
#define SM_BASE_DIGITS 9
/*SM_BASE 0 的個數為SM_BASE_DIGITS*/
#include<vector>
#include<iostream>
#include<iomanip>
#include<string>
#include<utility>/*for pair*/
class bigN{
private:
std::vector<int>s;
char sign;
inline void trim(){
while(!s.empty()&&!s.back())s.pop_back();
if(s.empty())sign=1;
}
inline char cmp(const bigN &v,bool is=1)const{
if(is){
if(sign>v.sign)return 1;
if(sign<v.sign)return -1;
}
char d=sign>0||!is?1:-1;
if(s.size()>v.s.size())return d;
if(s.size()<v.s.size())return -d;
for(int i=s.size()-1;i>=0;i--){
if(s[i]>v.s[i])return d;
if(s[i]<v.s[i])return -d;
}
return 0;
}
inline std::vector<int> convert_base(const std::vector<int> &a,int old_digits,int new_digits)const{
std::vector<long long> p(std::max(old_digits,new_digits)+1);
p[0]=1;
for(int i=1;i<(int)p.size();++i)p[i]=p[i-1]*10;
std::vector<int> ans;
long long cur=0;
int cur_digits=0;
for (int i=0;i<(int)a.size();++i){
cur+=a[i]*p[cur_digits];
cur_digits+=old_digits;
while(cur_digits>=new_digits){
ans.push_back(cur%p[new_digits]);
cur/=p[new_digits];
cur_digits-=new_digits;
}
}
ans.push_back((int)cur);
while (!ans.empty()&&!ans.back())ans.pop_back();
return ans;
}
inline std::vector<long long> karatsuba(const std::vector<long long> &a,const std::vector<long long> &b)const{
int n=a.size();
std::vector<long long> res(n*2);
if(n<=32){
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
res[i+j]+=a[i]*b[j];
return res;
}
int k=n/2;
std::vector<long long> a1(a.begin(),a.begin()+k);
std::vector<long long> a2(a.begin()+k,a.end());
std::vector<long long> b1(b.begin(),b.begin()+k);
std::vector<long long> b2(b.begin()+k,b.end());
std::vector<long long> a1b1=karatsuba(a1,b1);
std::vector<long long> a2b2=karatsuba(a2,b2);
for(int i=0;i<k;++i)a2[i]+=a1[i];
for(int i=0;i<k;++i)b2[i]+=b1[i];
std::vector<long long> r=karatsuba(a2,b2);
for(int i=0;i<(int)a1b1.size();++i)r[i]-=a1b1[i];
for(int i=0;i<(int)a2b2.size();++i)r[i]-=a2b2[i];
for(int i=0;i<(int)r.size();++i)res[i+k]+=r[i];
for(int i=0;i<(int)a1b1.size();++i)res[i]+=a1b1[i];
for(int i=0;i<(int)a2b2.size();++i)res[i+n]+=a2b2[i];
return res;
}
public:
/*初始化*/
bigN():sign(1){}
bigN(const long long &v){
*this=v;
}
bigN(const std::string &v){
*this=v;
}
/*等於運算子重載*/
inline void operator=(const bigN &v){
sign=v.sign;
s=v.s;
}
inline void operator=(long long v){
sign=1;s.clear();
if (v < 0)sign=-1,v=-v;
for(;v;v/=SM_BASE)s.push_back(v%SM_BASE);
}
inline void operator=(const std::string &v){
sign=1;s.clear();
int len=0;
for(;len<(int)v.size()&&(v[len]=='-'||v[len]=='+');len++)
if(v[len]=='-')sign=-1;
for(int i=v.size()-1;i>=len;i-=SM_BASE_DIGITS){
int x=0;
for(int j=std::max(len,i-SM_BASE_DIGITS+1);j<=i;j++)
x=x*10+v[j]-'0';
s.push_back(x);
}
trim();
}
/*加減運算子重載*/
inline bigN operator+(const bigN &v)const{
if(sign==v.sign){
bigN ans=v;
int len=std::max(s.size(),v.s.size());
for(int i=0,is=0;i<len||is;i++){
if(i==(int)ans.s.size())ans.s.push_back(0);
ans.s[i]+=is+(i<(int)s.size()?s[i]:0);
is=ans.s[i]>=SM_BASE;
if(is)ans.s[i]-=SM_BASE;
}
return ans;
}else return *this-(-v);
}
inline bigN operator-(const bigN &v)const{
if(sign==v.sign){
if(~cmp(v,0)){
bigN ans=*this;
for(int i=0,is=0;i<(int)v.s.size()||is;i++){
ans.s[i]-=is+(i<(int)v.s.size()?v.s[i]:0);
is=ans.s[i]<0;
if(is)ans.s[i]+=SM_BASE;
}
ans.trim();
return ans;
}else return -(v-*this);
}else return *this+(-v);
}
/*乘法運算子重載*/
inline bigN operator*(const bigN &v)const{
std::vector<int> a6=convert_base(s,SM_BASE_DIGITS,6);
std::vector<int> b6=convert_base(v.s,SM_BASE_DIGITS,6);
std::vector<long long> a(a6.begin(),a6.end());
std::vector<long long> b(b6.begin(),b6.end());
while(a.size()<b.size())a.push_back(0);
while(b.size()<a.size())b.push_back(0);
while(a.size()&(a.size()-1))a.push_back(0),b.push_back(0);
std::vector<long long> c=karatsuba(a,b);
bigN ans;
ans.sign=sign*v.sign;
for(int i=0,carry=0;i<(int)c.size();++i){
long long cur=c[i]+carry;
ans.s.push_back((int)(cur%1000000));
carry=(int)(cur/1000000);
}
ans.s=convert_base(ans.s,6,SM_BASE_DIGITS);
ans.trim();
return ans;
}
/*對整數的乘除做支援運算*/
inline void operator*=(int v){
if(v<0)sign=-sign,v=-v;
for(int i=0,is=0;i<(int)s.size()||is;i++){
if(i==(int)s.size())s.push_back(0);
long long a=s[i]*(long long)v+is;
is=(int)(a/SM_BASE);
s[i]=(int)(a%SM_BASE);
}
trim();
}
inline bigN operator*(int v){
bigN ans=*this;
ans*=v;
return ans;
}
inline void operator/=(int v){
if(v<0)sign=-sign,v=-v;
for(int i=s.size()-1,rem=0;i>=0;i--){
long long a=s[i]+rem*(long long)SM_BASE;
s[i]=(int)(a/v);
rem=a%v;
}
trim();
}
inline bigN operator/(int v){
bigN ans=*this;
ans/=v;
return ans;
}
inline int operator%(int v){
if(v<0)v=-v;
int m=0;
for(int i=s.size()-1;i>=0;i--)
m=(s[i]+m*(long long)SM_BASE)%v;
return m*sign;
}
/*除法,商為first,餘為second*/
inline friend std::pair<bigN,bigN>divmod(const bigN &a,const bigN &b){
int norm=SM_BASE/(b.s.back()+1);
bigN x=a.abs()*norm;
bigN y=b.abs()*norm;
bigN q,r;
q.s.resize(x.s.size());
for(int i=x.s.size()-1;i>=0;i--){
r*=SM_BASE;
r+=x.s[i];
int s1=r.s.size()<=y.s.size()?0:r.s[y.s.size()];
int s2=r.s.size()<=y.s.size()-1?0:r.s[y.s.size()-1];
int d=((long long)SM_BASE*s1+s2)/y.s.back();
r-=y*d;
while(r.cmp(0,1)==-1)r+=y,--d;
q.s[i]=d;
}
q.sign=a.sign*b.sign;
r.sign=a.sign;
q.trim();
r.trim();
return std::make_pair(q,r/norm);
}
inline bigN operator/(const bigN &v)const{
return divmod(*this,v).first;
}
inline bigN operator%(const bigN &v)const{
return divmod(*this,v).second;
}
/*數學指派運算子重載*/
inline void operator+=(const bigN &v){
*this=*this+v;
}
inline void operator-=(const bigN &v){
*this=*this-v;
}
inline void operator*=(const bigN &v){
*this=*this*v;
}
inline void operator/=(const bigN &v){
*this=*this/v;
}
inline void operator%=(const bigN &v){
*this=*this%v;
}
/*比較運算子重載*/
inline bool operator<(const bigN &v)const{
return cmp(v)<0;
}
inline bool operator>(const bigN &v)const{
return cmp(v)>0;
}
inline bool operator<=(const bigN &v)const{
return cmp(v)<=0;
}
inline bool operator>=(const bigN &v)const{
return cmp(v)>=0;
}
inline bool operator==(const bigN &v)const{
return !cmp(v);
}
inline bool operator!=(const bigN &v)const{
return cmp(v)!=0;
}
/*數學運算子重載*/
inline bigN abs()const{
bigN ans=*this;
ans.sign*=ans.sign;
return ans;
}
inline bigN operator-()const{
bigN ans=*this;
ans.sign=-sign;
return ans;
}
/* >>、<<運算子重載 */
friend std::istream& operator>>(std::istream &stream,bigN &v) {
std::string s;
stream>>s;
v=s;
return stream;
}
friend std::ostream& operator<<(std::ostream &stream,const bigN &v) {
if(v.sign==-1)stream<<'-';
stream<<(v.s.empty()?0:v.s.back());
for(int i=(int)v.s.size()-2;i>=0;i--)
stream<<std::setw(SM_BASE_DIGITS)<<std::setfill('0')<<v.s[i];
return stream;
}
/*是否為0*/
inline bool iszero(){
return !s.size()||(s.size()==1&&!s[0]);
}
/*形態重載*/
inline operator std::string(){
std::string ans,x;
if(s.empty())return "0";
if(sign==-1)ans+='-';
int o=s[s.size()-1];
while(o)x+=o%10+'0',o/=10;
for(int i=x.size()-1;i>=0;i--)ans+=x[i];
for(int i=s.size()-2;i>=0;i--){
std::string t;
int p=s[i];
for(int j=0;j<SM_BASE_DIGITS;j++){
t+=p%10+'0';p/=10;
}
for(int j=SM_BASE_DIGITS-1;j>=0;j--)ans+=t[j];
}
return ans;
}
};
#endif
#undef SM_BASE
#undef SM_BASE_DIGITS
#ifdef __linux__
#define gc getchar_unlocked
#elif _WIN32
#define gc getchar
#elif __APPLE__
#define gc getchar
#endif
template<typename T>
inline void gn(T &_){T __=1;char c=gc();_=0;while((c<'0'||c>'9')&&c!='-')c=gc();if(c=='-')__=-1,c=gc();while(c>='0'&&c<='9')_=_*10+c-'0',c=gc();_*=__;}
template <typename T, typename ...Args>
inline void gn(T &x, Args& ...args){gn(x);gn(args...);}
int main(){
cin.tie(0);ios::sync_with_stdio();
int n;
gn(n);
bigN l, r;
cin>>l>>r;
bigN ans=0;
for(int i=0;i<n;i++){
bigN pos;
cin>>pos;
int dir;
gn(dir);
if(dir==0){
if(pos-l < r-pos){
if(pos-l > ans){
ans=pos-l;
}
}else{
if(r-pos > ans){
ans=r-pos;
}
}
}else if(dir==1){
if(pos-l > ans){
ans=pos-l;
}
}else{
if(r-pos > ans){
ans=r-pos;
}
}
}
cout<<ans;
return 0;
}
留言
張貼留言