hdu多校5
1002
思路:贪心显然不好贪,直接爆搜。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 1e5 + 7; const int M = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; int x, k, mx, mn, Mn, Mx; string s; void getMx(string &a, int pos, int k, int n) { if(mx == Mx) return; if(k == 0 || pos == n) { int val = 0; for(int i = 0; i < n; i++) { val *= 10; val += a[i] - '0'; } mx = max(mx, val); return; } char val = '0'; for(int i = n - 1; i > pos; i--) val = max(val, a[i]); if(val <= a[pos]) { getMx(a, pos + 1, k, n); } else { for(int i = n - 1; i > pos; i--) { if(a[i] == val) { swap(a[i], a[pos]); getMx(a, pos + 1, k - 1, n); swap(a[i], a[pos]); } } } } void getMn(string &a, int pos, int k, int n) { if(mn == Mn) return; if(k == 0 || pos == n) { int val = 0; for(int i = 0; i < n; i++) { val *= 10; val += a[i] - '0'; } mn = min(mn, val); return; } if(pos == 0) { char val = '9'; for(int i = n - 1; i > pos; i--) if(a[i] != '0') val = min(val, a[i]); if(val >= a[pos]) { getMn(a, pos + 1, k, n); } else { for(int i = n - 1; i > pos; i--) { if(a[i] == val) { swap(a[i], a[pos]); getMn(a, pos + 1, k - 1, n); swap(a[i], a[pos]); } } } } else { char val = '9'; for(int i = n - 1; i > pos; i--) val = min(val, a[i]); if(val >= a[pos]) { getMn(a, pos + 1, k, n); } else { for(int i = n - 1; i > pos; i--) { if(a[i] == val) { swap(a[i], a[pos]); getMn(a, pos + 1, k - 1, n); swap(a[i], a[pos]); } } } } } int main() { int T; scanf("%d", &T); while(T--) { mn = inf; mx = -inf; Mx = Mn = 0; cin >> s >> k; string a = s, b = s; sort(s.rbegin(), s.rend()); for(int i = 0; i < s.size(); i++) { Mx *= 10; Mx += s[i] - '0'; } sort(s.begin(), s.end()); if(s[0] == '0') { for(int i = 1; i < s.size(); i++) { if(s[i] != '0') { swap(s[0], s[i]); break; } } } for(int i = 0; i < s.size(); i++) { Mn *= 10; Mn += s[i] - '0'; } getMx(a, 0, k, s.size()); getMn(b, 0, k, s.size()); printf("%d %d\n", mn, mx); } return 0; } /* */
1007
思路:线段树剪剪枝,标程好像是用st表压标记。
//#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack-protector") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native") //#pragma GCC optimize("unroll-loops") #include<bits/stdc++.h> #define fi first #define se second #define mp make_pair #define pb push_back #define pi acos(-1.0) #define ll long long #define ui unsigned int #define vi vector<int> #define mod 1000000007 #define ld long double #define C 0.5772156649 #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 #define pll pair<ll,ll> #define pil pair<int,ll> #define pli pair<ll,int> #define pii pair<int,int> #define cd complex<double> #define ull unsigned long long #define base 1000000000000000000 #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define fio ios::sync_with_stdio(false);cin.tie(0) template<typename T> inline T const& MAX(T const &a,T const &b){return a>b?a:b;} template<typename T> inline T const& MIN(T const &a,T const &b){return a<b?a:b;} inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;} inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;} inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;} inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;} using namespace std; const double eps=1e-8; const ll INF=0x3f3f3f3f3f3f3f3f; const int N=100000+10,maxn=15000000+10,inf=0x3f3f3f3f; unsigned int x,y,z; int n,m; unsigned int gao() { x=x^(x<<11); x=x^(x>>4); x=x^(x<<5); x=x^(x>>14); unsigned int w=x^(y^z); x=y; y=z; z=w; return z; } ui val[N<<2],lazy[N<<2]; void build(ui l,ui r,int rt) { val[rt]=lazy[rt]=0; if(l==r)return ; ui m=(l+r)>>1; build(ls),build(rs); } void update(ui L,ui R,ui c,ui l,ui r,int rt) { if(lazy[rt]>c)return ; if(L<=l&&r<=R) { lazy[rt]=MAX(lazy[rt],c); if(lazy[rt]>val[rt])val[rt]=lazy[rt]; return ; } ui m=(l+r)>>1; if(L<=m)update(L,R,c,ls); if(m<R)update(L,R,c,rs); } void pushdown(ui l,ui r,int rt) { ui m=(l+r)>>1; if(l==m)val[rt<<1]=MAX(val[rt<<1],lazy[rt]); if(m+1==r)val[rt<<1|1]=MAX(val[rt<<1|1],lazy[rt]); lazy[rt<<1]=MAX(lazy[rt<<1],lazy[rt]); lazy[rt<<1|1]=MAX(lazy[rt<<1|1],lazy[rt]); lazy[rt]=0; } ull ans; void query(ui l,ui r,int rt) { if(l==r) { ans^=(1ull*l*val[rt]); return ; } pushdown(l,r,rt); ui m=(l+r)>>1; query(ls),query(rs); } int main() { fio; int T;cin>>T; while(T--) { cin>>n>>m>>x>>y>>z; build(1,n,1); for(int i=0;i<m;i++) { ui a=gao(),b=gao(),c=gao(); ui l=MIN(a%n+1,b%n+1),r=MAX(a%n+1,b%n+1),v=c%(1<<30); update(l,r,v,1,n,1); } ans=0; query(1,n,1); cout<<ans<<"\n"; } return 0; } /******************** ********************/
1005
思路:简单计算几何? 我们队好像写的很麻烦。。。
#include<bits/stdc++.h> using namespace std; const double pi=acos(-1); struct Point { double x, y; Point(double x = 0, double y = 0) :x(x), y(y) {} }; typedef Point Vector; Vector operator - (Point A, Point B) { return Vector(A.x - B.x, A.y - B.y); } Vector operator + (Vector A, Vector B) { return Vector(A.x + B.x, A.y + B.y); } Vector operator * (Vector A, double p) { return Vector(A.x * p, A.y * p); } Vector operator / (Vector A, double p) { return Vector(A.x / p, A.y / p); } double Dot(Vector A,Vector B) { return A.x * B.x + A.y * B.y; } double Length(Vector A) { return sqrt(Dot(A,A)); } double Angle(Vector A,Vector B) //求角度 { return acos(Dot(A,B) / Length(A) / Length(B)); } double angle(Vector v) { return atan2(v.y,v.x); } const double eps = 1e-10; int dcmp(double x) { if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; } bool operator < (const Point& a,const Point& b) { return a.x < b.x || (a.x == b.x && a.y < b.y); } bool operator == (const Point& a,const Point &b) { return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; } struct Circle { Point c; double r; Circle(Point c, double r) :c(c), r(r) {} Point point(double a) { return Point(c.x + cos(a) * r, c.y + sin(a) * r); } }; int getCircleCircleIntersection(Circle C1,Circle C2,vector<Point>& sol) //求圆和圆的交点 { double d = Length(C1.c - C2.c); if(dcmp(d) == 0) //首先圆心要重合 { if(dcmp(C1.r - C2.r) == 0) return -1; //其次半径要相同,然后就可以推出两圆重合 return 0; } if(dcmp(C1.r + C2.r - d) < 0) return 0; //相离没交点 if(dcmp(fabs(C1.r - C2.r) - d) > 0) return 0; //圆在圆中,没有交点 double a = angle(C2.c - C1.c); //向量C1C2的极角 double da = acos((C1.r * C1.r + d * d - C2.r * C2.r) / (2 * C1.r * d)); //C1C2到C1P1的角 Point p1 = C1.point(a-da),p2 = C1.point(a+da); sol.push_back(p1); if(p1 == p2) return 1; //相切 sol.push_back(p2); return 2; //相交 } double Pointlen(Point a,Point b){ double res= sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); return res; } double ans; bool OnCircle(Point x,Circle y){ double len=(x.x-y.c.x)*(x.x-y.c.x)+(x.y-y.c.y)*(x.y-y.c.y); if(len<=y.r*y.r) return true; return false; } double dot(Point a, Point b) { return a.x * b.x + a.y * b.y; } int main(){ int T;scanf("%d",&T); while(T--){ int n; double xx; scanf("%d%lf",&n,&xx); Circle ori((Point){0,0},xx); ans=2.0*pi*ori.r; for(int i=0;i<n;i++){ vector<Point> inter; double tx,ty,tr; scanf("%lf%lf%lf",&tx,&ty,&tr); Circle tc((Point){tx,ty},tr); int num=getCircleCircleIntersection(ori,tc,inter); if(num==0||num==-1) continue; else if(num==1){ if(OnCircle(tc.c,ori)) ans+=2.0*tc.r*pi; } else{ double plen=Pointlen(inter[1],inter[0])/2.0; double slen=2.0*ori.r*asin(plen/ori.r); double llen=2.0*pi*ori.r-2.0*ori.r*asin(plen/ori.r); Point mid; mid.x=(inter[1].x+inter[0].x)/2.0; mid.y=(inter[1].y+inter[0].y)/2.0; double len1=Pointlen(ori.c,mid); double len2=Pointlen(tc.c,ori.c); double an1= 2.0*tc.r*asin(plen/tc.r); double an2=2.0*pi*tc.r - 2.0*tc.r*asin(plen/tc.r); if(dot(mid - ori.c, tc.c - ori.c) >= 0) { if(len1 <= len2) { ans -= min(slen, llen); ans += min(an1, an2); } else { ans -= min(slen, llen); ans += max(an1, an2); } } else { ans -= max(slen, llen); ans += min(an1, an2); } } } printf("%.12f\n",ans); } } /* 100 1 2.717 -1 0 2.717 */
补题*********************************************************
1008
思路:感觉这题应该想的出来的,但是比赛确实是没想出来,枚举反转的值,然后去dp。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define pii pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 1e5 + 7; const int M = 1e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 +7; int n, l, r, ans, tot, p1[10], p2[10], dp[N][13], a[N], f[N][13][2]; char s[N]; void solve(int S, int T) { tot = 0; memset(p1, -1, sizeof(p1)); memset(p2, -1, sizeof(p2)); for(int i = 0; i <= S; i++) p1[i] = tot++; for(int i = T; i >= S; i--) p2[i] = tot++; for(int i = T; i < 10; i++) p1[i] = tot++; for(int i = 0; i < tot; i++) dp[0][i] = 0, f[0][i][0] = f[0][i][1] = -1; for(int i = 1; i <= n; i++) { for(int j = 0; j < tot; j++) { dp[i][j] = dp[i - 1][j]; f[i][j][0] = f[i - 1][j][0]; f[i][j][1] = f[i - 1][j][1]; if(j && dp[i][j] < dp[i][j - 1]) { dp[i][j] = dp[i][j - 1]; f[i][j][0] = f[i][j - 1][0]; f[i][j][1] = f[i][j - 1][1]; } if(p1[a[i]] != -1 && dp[i - 1][p1[a[i]]] + 1 > dp[i][p1[a[i]]]) { dp[i][p1[a[i]]] = dp[i - 1][p1[a[i]]] + 1; f[i][p1[a[i]]][0] = f[i - 1][p1[a[i]]][0]; f[i][p1[a[i]]][1] = f[i - 1][p1[a[i]]][1]; } if(p2[a[i]] != -1 && dp[i - 1][p2[a[i]]] + 1 > dp[i][p2[a[i]]]) { dp[i][p2[a[i]]] = dp[i - 1][p2[a[i]]] + 1; if(f[i][p2[a[i]]][0] == -1) f[i][p2[a[i]]][0] = i; f[i][p2[a[i]]][1] = i; } } } if(dp[n][tot - 1] > ans) { ans = dp[n][tot - 1]; if(f[n][tot - 1][0] != -1) { l = f[n][tot - 1][0]; r = f[n][tot - 1][1]; } else { l = 1; r = 1; } } } int main() { int T; scanf("%d", &T); while(T--) { ans = 0; scanf("%d%s", &n, s + 1); for(int i = 1; i <= n; i++) a[i] = s[i] - '0'; for(int i = 0; i < 10; i++) { for(int j = i; j < 10; j++) { solve(i, j); } } printf("%d %d %d\n", ans, l, r); } return 0; } /* */