sgu 299
题意:给你n个线段,然后问你能不能选出其中三个组成一个三角形,数字很大
收获:另一个大整数模板
那么考虑下为什么如果连续三个不可以的话,一定是不存在呢?
连续上个不合法的话,一定是 ai-1 + ai-2 < = ai;
那么如果我们取右边的数,那是不是aj ,那么aj >= ai就更不可能成立了,
取左边的一样可以证明出不可以
#include<bits/stdc++.h> #define de(x) cout<<#x<<"="<<x<<endl; #define dd(x) cout<<#x<<"="<<x<<" "; #define rep(i,a,b) for(int i=a;i<(b);++i) #define repd(i,a,b) for(int i=a;i>=(b);--i) #define repp(i,a,b,t) for(int i=a;i<(b);i+=t) #define ll long long #define mt(a,b) memset(a,b,sizeof(a)) #define fi first #define se second #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define pii pair<int,int> #define pdd pair<double,double> #define pdi pair<double,int> #define mp(u,v) make_pair(u,v) #define sz(a) (int)a.size() #define ull unsigned long long #define ll long long #define pb push_back #define PI acos(-1.0) #define qc std::ios::sync_with_stdio(false) #define db double #define all(a) a.begin(),a.end() const int mod = 1e9+7; const int maxn = 1e3+6; const double eps = 1e-6; using namespace std; class bign { public: int len, s[maxn];//数的长度,记录数组 //构造函数 bign(); bign(const char*); bign(int); bool sign;//符号 1正数 0负数 string toStr() const;//转化为字符串,主要是便于输出 friend istream& operator>>(istream &,bign &);//重载输入流 friend ostream& operator<<(ostream &,bign &);//重载输出流 //重载复制 bign operator=(const char*); bign operator=(int); bign operator=(const string); //重载各种比较 bool operator>(const bign &) const; bool operator>=(const bign &) const; bool operator<(const bign &) const; bool operator<=(const bign &) const; bool operator==(const bign &) const; bool operator!=(const bign &) const; //重载四则运算 bign operator+(const bign &) const; bign operator++(); bign operator++(int); bign operator+=(const bign&); bign operator-(const bign &) const; bign operator--(); bign operator--(int); bign operator-=(const bign&); bign operator*(const bign &)const; bign operator*(const int num)const; bign operator*=(const bign&); bign operator/(const bign&)const; bign operator/=(const bign&); //四则运算的衍生运算 bign operator%(const bign&)const;//取模(余数) bign factorial()const;//阶乘 bign Sqrt()const;//整数开根(向下取整) bign pow(const bign&)const;//次方 //一些乱乱的函数 void clean(); ~bign(); }; #define max(a,b) a>b ? a : b #define min(a,b) a<b ? a : b bign::bign() { memset(s, 0, sizeof(s)); len = 1; sign = 1; } bign::bign(const char *num) { *this = num; } bign::bign(int num) { *this = num; } string bign::toStr() const { string res; res = ""; for (int i = 0; i < len; i++) res = (char)(s[i] + '0') + res; if (res == "") res = "0"; if (!sign&&res != "0") res = "-" + res; return res; } istream &operator>>(istream &in, bign &num) { string str; in>>str; num=str; return in; } ostream &operator<<(ostream &out, bign &num) { out<<num.toStr(); return out; } bign bign::operator=(const char *num) { memset(s, 0, sizeof(s)); char a[maxn] = ""; if (num[0] != '-') strcpy(a, num); else for (int i = 1; i < strlen(num); i++) a[i - 1] = num[i]; sign = !(num[0] == '-'); len = strlen(a); for (int i = 0; i < strlen(a); i++) s[i] = a[len - i - 1] - 48; return *this; } bign bign::operator=(int num) { if (num < 0) sign = 0, num = -num; else sign = 1; char temp[maxn]; sprintf(temp, "%d", num); *this = temp; return *this; } bign bign::operator=(const string num) { const char *tmp; tmp = num.c_str(); *this = tmp; return *this; } bool bign::operator<(const bign &num) const { if (sign^num.sign) return num.sign; if (len != num.len) return len < num.len; for (int i = len - 1; i >= 0; i--) if (s[i] != num.s[i]) return sign ? (s[i] < num.s[i]) : (!(s[i] < num.s[i])); return !sign; } bool bign::operator>(const bign&num)const { return num < *this; } bool bign::operator<=(const bign&num)const { return !(*this>num); } bool bign::operator>=(const bign&num)const { return !(*this<num); } bool bign::operator!=(const bign&num)const { return *this > num || *this < num; } bool bign::operator==(const bign&num)const { return !(num != *this); } bign bign::operator+(const bign &num) const { if (sign^num.sign) { bign tmp = sign ? num : *this; tmp.sign = 1; return sign ? *this - tmp : num - tmp; } bign result; result.len = 0; int temp = 0; for (int i = 0; temp || i < (max(len, num.len)); i++) { int t = s[i] + num.s[i] + temp; result.s[result.len++] = t % 10; temp = t / 10; } result.sign = sign; return result; } bign bign::operator++() { *this = *this + 1; return *this; } bign bign::operator++(int) { bign old = *this; ++(*this); return old; } bign bign::operator+=(const bign &num) { *this = *this + num; return *this; } bign bign::operator-(const bign &num) const { bign b=num,a=*this; if (!num.sign && !sign) { b.sign=1; a.sign=1; return b-a; } if (!b.sign) { b.sign=1; return a+b; } if (!a.sign) { a.sign=1; b=bign(0)-(a+b); return b; } if (a<b) { bign c=(b-a); c.sign=false; return c; } bign result; result.len = 0; for (int i = 0, g = 0; i < a.len; i++) { int x = a.s[i] - g; if (i < b.len) x -= b.s[i]; if (x >= 0) g = 0; else { g = 1; x += 10; } result.s[result.len++] = x; } result.clean(); return result; } bign bign::operator * (const bign &num)const { bign result; result.len = len + num.len; for (int i = 0; i < len; i++) for (int j = 0; j < num.len; j++) result.s[i + j] += s[i] * num.s[j]; for (int i = 0; i < result.len; i++) { result.s[i + 1] += result.s[i] / 10; result.s[i] %= 10; } result.clean(); result.sign = !(sign^num.sign); return result; } bign bign::operator*(const int num)const { bign x = num; bign z = *this; return x*z; } void bign::clean() { if (len == 0) len++; while (len > 1 && s[len - 1] == '\0') len--; } bign::~bign() { } bign a[maxn]; int main(){ int n; scanf("%d",&n); rep(i,1,n+1) cin>>a[i]; sort(a+1,a+n+1); rep(i,3,n+1) if(a[i] < a[i-1] + a[i-2]) { cout<<a[i]<<" "<<a[i-1]<<" "<<a[i-2]<<endl; return 0; } puts("0 0 0"); return 0; }
sgu 230
题意:告诉你硬币1 到 n,然后重量依次递增,然后给你n个盒子,然后让你用n个盒子装这n个硬币,然后重量大的
要装重量大的硬币
收获:好好看题意,拓扑
#include<bits/stdc++.h> #define de(x) cout<<#x<<"="<<x<<endl; #define dd(x) cout<<#x<<"="<<x<<" "; #define rep(i,a,b) for(int i=a;i<(b);++i) #define repd(i,a,b) for(int i=a;i>=(b);--i) #define repp(i,a,b,t) for(int i=a;i<(b);i+=t) #define ll long long #define mt(a,b) memset(a,b,sizeof(a)) #define fi first #define se second #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define pii pair<int,int> #define pdd pair<double,double> #define pdi pair<double,int> #define mp(u,v) make_pair(u,v) #define sz(a) (int)a.size() #define ull unsigned long long #define ll long long #define pb push_back #define PI acos(-1.0) #define qc std::ios::sync_with_stdio(false) #define db double #define all(a) a.begin(),a.end() const int mod = 1e9+7; const int maxn = 2e2+5; const double eps = 1e-6; using namespace std; bool eq(const db &a, const db &b) { return fabs(a - b) < eps; } bool ls(const db &a, const db &b) { return a + eps < b; } bool le(const db &a, const db &b) { return eq(a, b) || ls(a, b); } ll gcd(ll a,ll b) { return a==0?b:gcd(b%a,a); }; ll lcm(ll a,ll b) { return a/gcd(a,b)*b; } ll kpow(ll a,ll b) {ll res=1; if(b<0) return 1; for(;b;b>>=1){if(b&1)res=res*a;a=a*a;}return res;} ll read(){ ll x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m; int in[maxn]; vector<int> G[maxn],ans; bool topo(){ queue<int> q; while(sz(q)) q.pop(); rep(i,1,n+1) if(!in[i]) q.push(i); while(sz(q)){ int u = q.front(); q.pop(); ans.pb(u); rep(i,0,sz(G[u])){ int v = G[u][i]; in[v]--; if(!in[v]) q.push(v); } } return sz(ans) == n; } int a[maxn]; int main(){ scanf("%d%d",&n,&m); rep(i,0,m) { int u,v; scanf("%d%d",&u,&v); G[u].pb(v); in[v]++; } if(!topo()) return puts("No solution"),0; rep(i,0,sz(ans)) a[ans[i]]=i+1;//printf("%d%c",ans[i]," \n"[i+1==sz(ans)]); rep(i,1,n+1) printf("%d%c",a[i]," \n"[i==n]); return 0; }
sgu 249
题意:给你0到2^(n+m)-1这些数字,要你放到2^n行,2^m列的矩形里,要求相邻两个数字的二进制只差一位
收获:格雷码
#include<bits/stdc++.h> #define de(x) cout<<#x<<"="<<x<<endl; #define dd(x) cout<<#x<<"="<<x<<" "; #define rep(i,a,b) for(int i=a;i<(b);++i) #define repd(i,a,b) for(int i=a;i>=(b);--i) #define repp(i,a,b,t) for(int i=a;i<(b);i+=t) #define ll long long #define mt(a,b) memset(a,b,sizeof(a)) #define fi first #define se second #define inf 0x3f3f3f3f #define INF 0x3f3f3f3f3f3f3f3f #define pii pair<int,int> #define pdd pair<double,double> #define pdi pair<double,int> #define mp(u,v) make_pair(u,v) #define sz(a) (int)a.size() #define ull unsigned long long #define ll long long #define pb push_back #define PI acos(-1.0) #define qc std::ios::sync_with_stdio(false) #define db double #define all(a) a.begin(),a.end() const int mod = 1e9+7; const int maxn = 1e5+5; const double eps = 1e-6; using namespace std; bool eq(const db &a, const db &b) { return fabs(a - b) < eps; } bool ls(const db &a, const db &b) { return a + eps < b; } bool le(const db &a, const db &b) { return eq(a, b) || ls(a, b); } ll gcd(ll a,ll b) { return a==0?b:gcd(b%a,a); }; ll lcm(ll a,ll b) { return a/gcd(a,b)*b; } ll kpow(ll a,ll b) {ll res=1;a%=mod; if(b<0) return 1; for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} ll read(){ ll x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } //inv[1]=1; //for(int i=2;i<=n;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod; //格雷码的相邻数,二进制只差一位 int main(){ int n,m; scanf("%d%d",&n,&m); rep(i,0,1<<n) rep(j,0,1<<m) printf("%d%c",(((i^(i>>1))<<m)) | (j^(j>>1))," \n"[j+1==(1<<m)]); return 0; }