湖南省2011年程序设计大赛题解
2014-07-18 20:46
274 查看
做的时候卡傻了。贴一下标程。
A,水题:
B,水题,不过被卡了= =
D,神奇的搜索姿势,表示不会。
E,挺水的。
G,没懂。
H,计算几何,不会。
I,感觉是快速幂加速的dp;
学姐告诉我被虐是很正常的,要有一个良好的心态去对待各种比赛。
A,水题:
#include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> using namespace std; int cases; int main() { double cl = clock(); scanf("%d", &cases); while( cases-- ) { char a[10]; scanf("%s", a); if( strlen(a) > 3 ) puts("3"); else { if( ( a[0] == 'o' ) + ( a[1] == 'n' ) + ( a[2] == 'e' ) >= 2 ) puts("1"); else puts("2"); } } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }
B,水题,不过被卡了= =
#include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> using namespace std; bool isImp7( int i ) { if( !(i % 7) ) return true; while(i) { if( i % 10 == 7 ) return true; i /= 10; } return false; } int main() { double cl = clock(); int n, m, k; while( scanf("%d %d %d", &n, &m, &k) == 3 && n ) { int cnt = 0, period = 2 * n - 2; if( n == m || m == 1 ) { for( int i = m; ; i += period ) if( isImp7( i ) ) { cnt++; if( cnt == k ) { printf("%d\n", i); break; } } } else { int next = 2 - m; for( int i = m; ; swap( next, i ) ) { next += period; if( isImp7( i ) ) { cnt++; if( cnt == k ) { printf("%d\n", i); break; } } } } } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }C,暴力匹配就行吧,数据那么弱,。。。
#include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> using namespace std; int m, n; char bigp[15][15], smallp[15][15]; int countStar( char a[15][15], int n ) { int res = 0; for( int i = 0; i < n; i++ ) for( int j = 0; j < n; j++ ) res += ( a[i][j] == '*' ); return res; } bool isValid( int x, int y ) { return x >= 0 && x < n && y >= 0 && y < n; } bool isSame( int i, int j ) { for( int x = 0; x < m; x++ ) for( int y = 0; y < m; y++ ) if( smallp[x][y] == '*' ) if( !isValid( x + i, y + j ) || bigp[x+i][y+j] != '*' ) return false; return true; } bool canMatch( int k, int i, int j ) { if( !k ) return true; if( i == n ) return false; if( j == n ) return canMatch( k, i + 1, -10 ); if( isSame( i, j ) ) { for( int x = 0; x < m; x++ ) for( int y = 0; y < m; y++ ) if( smallp[x][y] == '*' ) bigp[x+i][y+j] = '.'; if( canMatch( k - 1, i, j ) ) return true; for( int x = 0; x < m; x++ ) for( int y = 0; y < m; y++ ) if( smallp[x][y] == '*' ) bigp[x+i][y+j] = '*'; } return canMatch( k, i, j + 1 ); } int main() { double cl = clock(); while( scanf("%d %d", &n, &m) == 2 && m + n ) { for( int i = 0; i < n; i++ ) scanf("%s", bigp[i]); for( int i = 0; i < m; i++ ) scanf("%s", smallp[i]); int cnt1 = countStar( bigp, n ); int cnt2 = countStar( smallp, m ); if( cnt1 != cnt2 * 2 || !canMatch(2, -10, -10) ) puts("0"); else puts("1"); } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }
D,神奇的搜索姿势,表示不会。
#include <vector> #include <list> #include <map> #include <set> #include <deque> #include <queue> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <ctime> using namespace std; char a[15][15]; char a1[15][15]; char best[15][15]; vector<pair<int,int> > p; int d[100]; int used[100]; int nn,n; void search2(int x) { int i,j,k,xx,yy,cnt,start,dx,dy; vector<int> q; if (x==nn) { memcpy(a1,a,sizeof(a1)); memset(used,0,sizeof(used)); q.clear(); q.push_back(0); used[0]=1; for (i=0;i<q.size();i++) { xx=p[d[q[i]]].first; yy=p[d[q[i]]].second; for (j=0;j<nn;j++) if ((used[j]==0)&&(abs(p[d[j]].first-xx)+abs(p[d[j]].second-yy)==1)) { used[j]=1; q.push_back(j); } } if (q.size()!=nn) return; memset(used,0,sizeof(used)); for (i=0;i<nn;i++) { used[d[i]]=1; a1[p[d[i]].first][p[d[i]].second]='A'; } cnt=1; for (i=0;i<p.size();i++) if (used[i]==0) { used[i]=1; a1[p[i].first][p[i].second]='A'+cnt; for (j=1;j<nn;j++) { dx=p[d[j]].first-p[d[0]].first; dy=p[d[j]].second-p[d[0]].second; xx=p[i].first+dx; yy=p[i].second+dy; for (k=0;k<p.size();k++) if ((used[k]==0)&&(p[k].first==xx)&&(p[k].second==yy)) break; if (k==p.size()) return; used[k]=1; a1[xx][yy]='A'+cnt; } cnt++; } for (i=0;i<n;i++) for (j=0;j<n;j++) { if (best[i][j]<a1[i][j]) return; if (best[i][j]>a1[i][j]) { memcpy(best,a1,sizeof(a1)); return; } } return; } if (x==0) start=0; else start=d[x-1]+1; for (i=start;i<p.size();i++) { d[x]=i; search2(x+1); } } void search1(int x) { int i,j,k,start,dx,dy,xx,yy; vector<int> aa; vector<int> q; if (x==nn) { memcpy(a1,a,sizeof(a)); memset(used,0,sizeof(used)); for (i=0;i<nn;i++) { used[d[i]]=1; a1[p[d[i]].first][p[d[i]].second]='A'+i; } aa.clear(); aa.push_back(d[0]); for (i=0;i<p.size();i++) if (used[i]==0) { aa.push_back(i); used[i]=1; a1[p[i].first][p[i].second]='A'+0; for (j=1;j<nn;j++) { dx=p[d[j]].first-p[d[0]].first; dy=p[d[j]].second-p[d[0]].second; xx=p[i].first+dx; yy=p[i].second+dy; for (k=0;k<p.size();k++) if ((used[k]==0)&&(p[k].first==xx)&&(p[k].second==yy)) { used[k]=1;break; } if (k==p.size()) return; a1[p[k].first][p[k].second]='A'+j; } } memset(used,0,sizeof(used)); q.clear(); q.push_back(0); used[0]=1; for (i=0;i<q.size();i++) { xx=p[aa[q[i]]].first; yy=p[aa[q[i]]].second; for (j=0;j<aa.size();j++) if ((used[j]==0)&&(abs(p[aa[j]].first-xx)+abs(p[aa[j]].second-yy)==1)) { used[j]=1; q.push_back(j); } } if (q.size()!=aa.size()) return; for (i=0;i<n;i++) for (j=0;j<n;j++) { if (best[i][j]<a1[i][j]) return; if (best[i][j]>a1[i][j]) { memcpy(best,a1,sizeof(a1)); return; } } return; } if (x==0) start=0; else start=d[x-1]+1; for (i=start;i<p.size();i++) { d[x]=i; search1(x+1); } } int main() { int i,j,cnt; double cl = clock(); while (scanf("%d",&n)!=EOF) { if (n==0) break; for (i=0;i<n;i++) scanf("%s",a[i]); cnt=0; p.clear(); for (i=0;i<n;i++) for (j=0;j<n;j++) if (a[i][j]=='*') { p.push_back(make_pair(i,j)); cnt++; } memset(best,0,sizeof(best)); for (i=0;i<n;i++) for (j=0;j<n;j++) best[i][j]='a'; for (i=2;i<=cnt;i++) if (cnt%i==0) { j=cnt/i; if (i<=j) { nn=i; search1(0); } else { nn=j; search2(0); } if (best[0][0]!='a') break; } for (i=0;i<n;i++) printf("%s\n",best[i]); printf("\n"); } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }
E,挺水的。
#include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> using namespace std; int grundy( int n ) { if( n == 1 ) return 0; if( n & 1 ) return grundy( n/2 ); return n/2; } int main() { double cl = clock(); int n; while( scanf("%d", &n) == 1 && n ) { printf("%s\n", grundy(n) ? "Alice" : "Bob"); } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }F,三维的dp,有点不好写吧。
#include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> using namespace std; const double inf = 1e50; const int NN = 10005; int n, P; struct info { int p1, p2, t1, t2, w1, w2; }A[NN]; double dp[2][101][7]; int main() { double cl = clock(); while( scanf("%d %d", &n, &P) == 2 && n ) { for( int i = 1; i <= n; i++ ) scanf("%d %d %d %d %d %d", &A[i].p1, &A[i].p2, &A[i].t1, &A[i].t2, &A[i].w1, &A[i].w2); for( int i = 1; i <= 100; i++ ) for( int j = 0; j <= 6; j++ ) dp[0][i][j] = inf; dp[0][P][0] = 0; int cur = 1, prev = 0; for( int k = 1; k <= n; k++ ) { for( int i = 1; i <= 100; i++ ) for( int j = 0; j <= 6; j++ ) dp[cur][i][j] = inf; for( int i = 1; i <= 100; i++ ) for( int j = 0; j <= 6; j++ ) if( dp[prev][i][j] < inf && i >= A[k].p1 ) { int i1 = i + A[k].w1; int j1 = j + A[k].w2; if( i1 * (1 << j1) >= 100 ) i1 = 100, j1 = 0; double r; if( i >= A[k].p2 ) r = A[k].t2; else r = A[k].t2 + (A[k].p2 - i + 0.) * ( A[k].t1 - A[k].t2 ) / (A[k].p2 - A[k].p1); dp[cur][i1][j1] = min( dp[cur][i1][j1], r + dp[prev][i][j] ); } for( int j = 6; j > 0; j-- ) for( int i = 1; i <= 100; i++ ) if( dp[cur][i][j] < inf ) { int i1 = min( i * 2, 100 ); int j1 = j - 1; dp[cur][i1][j1] = min( dp[cur][i1][j1], dp[cur][i][j] ); } swap( cur, prev ); } double res = inf; for( int j = 6; j >= 0; j-- ) for( int i = 1; i <= 100; i++ ) res = min( res, dp[prev][i][j] ); if(res > inf/2) printf("Impossible\n"); else printf("%.2lf\n", res + 1e-11); } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }
G,没懂。
#include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> using namespace std; const int NN = 205; const int inf = 100000000; const int MOD = 1000000009; int n, A[NN][NN], val[NN][NN], dp[NN][NN], state[NN][NN], caseno; int dx[] = {0, 0, 1, -1}; int dy[] = {1, -1, 0, 0}; int isvalid( int x, int y ) { return x >= 0 && x < n && y >= 0 && y < n && x <= y; } int call( int i, int j ) { if( i == 0 && j == n - 1 ) return 1; int &ret = dp[i][j]; int &st = state[i][j]; if( st == caseno ) return ret; st = caseno; ret = 0; for( int k = 0; k < 4; k++ ) { int x = i + dx[k]; int y = j + dy[k]; if( isvalid( x, y ) && val[x][y] + A[i][j] == val[i][j] ) ret = ( ret + call( x, y ) ) % MOD; } return ret; } int main() { double cl = clock(); while( scanf("%d", &n) == 1 && n ) { for( int i = n - 1; i >= 0; i-- ) for( int j = 0; j < n; j++ ) scanf("%d", &A[j][i]); for( int i = 0; i < n; i++ ) for( int j = i + 1; j < n; j++ ) A[i][j] += A[j][i]; for( int i = 0; i < n; i++ ) for( int j = i; j < n; j++ ) val[i][j] = inf; queue <int> Q; Q.push( 0 ); Q.push( n - 1 ); val[0][n - 1] = A[0][n - 1]; while( !Q.empty() ) { int u = Q.front(); Q.pop(); int v = Q.front(); Q.pop(); for( int k = 0; k < 4; k++ ) { int x = u + dx[k]; int y = v + dy[k]; if( isvalid( x, y ) && val[x][y] > val[u][v] + A[x][y] ) { val[x][y] = val[u][v] + A[x][y]; Q.push(x); Q.push(y); } } } int mn = inf, res = 0; for( int i = 0; i < n; i++ ) mn = min( mn, val[i][i] ); ++caseno; for( int i = 0; i < n; i++ ) if( val[i][i] == mn ) res = ( res + call( i, i ) ) % MOD; printf("%d\n", res); } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }
H,计算几何,不会。
/* Author : Jan Problem Name : Algorithm : Complexity : */ #include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> using namespace std; const double eps = 1e-9; const double pi = 2 * acos( 0.0 ); inline bool eq(double a, double b) { return fabs( a - b ) < eps; } inline bool eq2(double a, double b) { return fabs( a - b ) < 1e-7; } struct point { double x, y; point() {} point( double xx, double yy ) { x = xx, y = yy; } bool operator < ( const point &b ) const { if( eq( x, b.x ) ) { if( eq( y, b.y ) ) return false; return y < b.y; } return x < b.x; } }; struct line { double a, b, c; line() {} line( point p1,point p2 ) { a=p1.y-p2.y; b=p2.x-p1.x; c=p1.x*p2.y-p2.x*p1.y; } }; struct circle { point center; double r; circle() {} circle( point P, double rr ) { center = P; r = rr; } }; struct segment { point A, B; segment() {} segment( point P1, point P2 ) { A = P1, B = P2; } }; inline double Distance( point a, point b ) { return sqrt( ( a.x - b.x ) * ( a.x - b.x ) + ( a.y - b.y ) * ( a.y - b.y ) ); } inline double Distance( point P, line L ) { return fabs( L.a * P.x + L.b * P.y + L.c ) / sqrt( L.a * L.a + L.b * L.b ); } inline double isleft( point p0, point p1, point p2 ) { return( ( p1.x - p0.x ) * ( p2.y - p0.y ) - ( p2.x - p0.x ) * ( p1.y - p0.y ) ); } inline bool intersection( line L1, line L2, point &p ) { double det = L1.a * L2.b - L1.b * L2.a; if( eq ( det, 0 ) ) return false; p.x = ( L1.b * L2.c - L2.b * L1.c ) / det; p.y = ( L1.c * L2.a - L2.c * L1.a ) / det; return true; } inline bool intersection( segment L1, segment L2, point &p ) { if( !intersection( line( L1.A, L1.B ), line( L2.A, L2.B ), p) ) return false; return(eq(Distance(L1.A,p)+Distance(L1.B,p),Distance(L1.A,L1.B)) && eq(Distance(L2.A,p)+Distance(L2.B,p),Distance(L2.A,L2.B))); } inline line findPerpendicularLine( line L, point P ) { line res; res.a = L.b, res.b = -L.a; res.c = -res.a * P.x - res.b * P.y; return res; } inline double Distance( point P, segment S ) { line L1 = line( S.A, S.B ), L2; point P1; L2 = findPerpendicularLine( L1, P ); if( intersection( L1, L2, P1 ) ) if( eq2 ( Distance( S.A, P1 ) + Distance( S.B, P1 ), Distance( S.A, S.B ) ) ) return Distance(P,L1); return min ( Distance( S.A, P), Distance( S.B, P) ); } const int MAX_LINE = 25; const int MAX_CIRCLE = 25; int n, m, L, W, sv[MAX_LINE*MAX_LINE]; segment S[MAX_LINE]; point P[MAX_LINE*MAX_LINE]; circle C[MAX_CIRCLE]; map <point, int> M; set <point> adjLine[MAX_LINE]; vector <int> adj[MAX_LINE*MAX_LINE]; vector <bool> taken[MAX_LINE*MAX_LINE]; vector <double> res[MAX_CIRCLE]; int getId( point p ) { if( M.find(p) == M.end() ) { int N = M.size(); M[p] = N; adj .clear(); P = p; } return M[p]; } double areaPolygon( int sv[], int n ) { double area = 0; for( int i = 0, j = n - 1; i < n; j = i++ ) area += P[sv[j]].x * P[sv[i]].y - P[sv[j]].y * P[sv[i]].x; return fabs(area)/2; } bool intersect( circle C, int sv[], int k ) { vector <point> V; for( int i = 0; i <= k; i++ ) { V.push_back( P[ sv[i] ] ); V[i].x -= C.center.x; V[i].y -= C.center.y; } bool flag = true; for( int i = 0; i < k; i++ ) { double dsq = V[i].x*V[i].x + V[i].y*V[i].y; double rsq = C.r * C.r; if( dsq + eps < rsq ) return true; if( dsq > rsq + eps ) flag = false; } if( flag ) return true; flag = true; for( int i = 0; i < k; i++ ) if( isleft( V[i], V[i+1], point(0, 0) ) < -eps ) { flag = false; break; } if( flag ) return true; // for all other cases, at least one edge of the polygon should intersect with the circle for( int i = 0; i < k; i++ ) if( Distance( point(0, 0), segment( V[i], V[i+1] ) ) + eps < C.r ) return true; return false; } void makeChain( int k ) { if( sv[k-1] == sv[0] ) { // full chain double area = areaPolygon( sv, k - 1 ); for( int i = 0; i < m; i++ ) if( intersect( C[i], sv, k - 1 ) ) res[i].push_back( area ); return; } int u = sv[k-1], j = -1; for( int i = 0; i < adj[u].size(); i++ ) { int v = adj[u][i]; if( v == sv[k-2] ) continue; if( isleft( P[sv[k-2]], P[sv[k-1]], P[v] ) > eps ) { if( j == -1 || isleft( P[ sv[k-1] ], P[ adj[u][j] ], P[ v ] ) > eps ) j = i; } } if( j == -1 ) return; taken[u][j] = true; sv[k] = adj[u][j]; makeChain( k + 1 ); } int main() { //freopen("h1.in", "r", stdin); //freopen("h1jan.ans", "w", stdout); double cl = clock(); while( scanf("%d %d %d %d", &n, &m, &L, &W) == 4 && n ) { for( int i = 0; i < n; i++ ) scanf("%lf %lf %lf %lf", &S[i].A.x, &S[i].A.y, &S[i].B.x, &S[i].B.y); for( int i = 0; i < m; i++ ) scanf("%lf %lf %lf", &C[i].center.x, &C[i].center.y, &C[i].r); S[n++] = segment( point( 0, 0 ), point( L, 0 ) ); S[n++] = segment( point( 0, 0 ), point( 0, W ) ); S[n++] = segment( point( 0, W ), point( L, W ) ); S[n++] = segment( point( L, 0 ), point( L, W ) ); for( int i = 0; i < n; i++ ) adjLine[i].clear(); for( int i = 0; i < m; i++ ) res[i].clear(); M.clear(); for( int i = 0; i < n; i++ ) { for( int j = i + 1; j < n; j++ ) { point p; if( intersection( S[i], S[j], p ) ) { int x = getId(p); adjLine[i].insert(p); adjLine[j].insert(p); } } } for( int i = 0; i < n; i++ ) { vector <point> V; for( set <point> ::iterator s = adjLine[i].begin(); s != adjLine[i].end(); s++ ) V.push_back( *s ); for( int j = 0; j < V.size() - 1; j++ ) { adj[ M[ V[j] ] ].push_back( M[ V[j + 1] ] ); adj[ M[ V[j + 1] ] ].push_back( M[ V[j] ] ); } } for( int i = 0; i < M.size(); i++ ) { taken[i].clear(); for( int j = 0; j < adj[i].size(); j++ ) taken[i].push_back(false); } for( int i = 0; i < M.size(); i++ ) { for( int j = 0; j < adj[i].size(); j++ ) if( !taken[i][j] ) { taken[i][j] = true; sv[0] = i; sv[1] = adj[i][j]; makeChain( 2 ); } } for( int i = 0; i < m; i++ ) { printf("%d", res[i].size()); sort( res[i].begin(), res[i].end() ); for( int j = 0; j < res[i].size(); j++ ) printf(" %.2lf", res[i][j] + 1e-7); puts(""); } puts(""); } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }
I,感觉是快速幂加速的dp;
#include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> using namespace std; typedef long long i64; const int MOD = 1000000009; const int NN = 256; // recurrence: f(n, k) = f(n-k, k) + f(n-k, k-1) * 4 + f(n-k, k-2) * 6 + f(n-k, k-3) * 4 + f(n-k, k-4) int n, k, N, pos[18][18];; int base[NN][NN], res[NN][NN], temp[NN][NN]; int multiply( int A[NN][NN], int B[NN][NN], int C[NN][NN] ) { for( int i = 0; i < N; i++ ) for( int j = 0; j < N; j++ ) { temp[i][j] = 0; for( int k = 0; k < N; k++ ) if( A[i][k] && B[k][j] ) temp[i][j] = ( temp[i][j] + A[i][k] * (i64)B[k][j] ) % MOD; } for( int i = 0; i < N; i++ ) for( int j = 0; j < N; j++ ) C[i][j] = temp[i][j]; } void buildBase() { for( int i = 0; i < N; i++ ) { for( int j = 0; j < N; j++ ) base[i][j] = res[i][j] = 0; res[i][i] = 1; } // build base int x = 0; for( int j = k; j >= 1; j-- ) for( int i = k + 1; i > 1; i-- ) { if( pos[i][j] == -1 ) { int p = i - j, q = j; if( p >= 1 ) { assert( pos[p][q] > -1 ); base[x][ pos[p][q] ] = 1; q--; if( q > 0 ) { assert( pos[p][q] > -1 ); base[x][ pos[p][q] ] = 4; q--; if( q > 0 ) { assert( pos[p][q] > -1 ); base[x][ pos[p][q] ] = 6; q--; if( q > 0 ) { assert( pos[p][q] > -1 ); base[x][ pos[p][q] ] = 4; q--; if( q > 0 ) { assert( pos[p][q] > -1 ); base[x][ pos[p][q] ] = 1; } } } } } } else base[x][ pos[i][j] ] = 1; x++; } } int solve() { int dp[20][17] = {0}; dp[0][0] = 1; for( int i = 1; i < 20; i++ ) { for( int j = 1; j <= k; j++ ) { int p = i - j, q = j; if( p >= 0 && q >= 0 ) dp[i][j] = (dp[i][j] + dp[p][q]) % MOD; q--; if( p >= 0 && q >= 0 ) dp[i][j] = (dp[i][j] + 4 * (i64) dp[p][q]) % MOD; q--; if( p >= 0 && q >= 0 ) dp[i][j] = (dp[i][j] + 6 * (i64) dp[p][q]) % MOD; q--; if( p >= 0 && q >= 0 ) dp[i][j] = (dp[i][j] + 4 * (i64) dp[p][q]) % MOD; q--; if( p >= 0 && q >= 0 ) dp[i][j] = (dp[i][j] + dp[p][q]) % MOD; } } if( n < 20 ) { int r = 0; for( int i = 1; i <= k; i++ ) r = ( r + dp [i] ) % MOD; return r; } int f[NN] = {0}, f1[NN] = {0}; N = 0; memset( pos, -1, sizeof(pos) ); for( int i = k; i >= 1; i-- ) for( int j = k; j >= 1; j-- ) { f = dp[j][i]; pos[j][i] = N++; } buildBase(); int p = n - k; while( p ) { if( p & 1 ) multiply( res, base, res ); multiply( base, base, base ); p >>= 1; } for( int i = 0; i < N; i++ ) for( int k = 0; k < N; k++ ) if( f[k] && res[i][k] ) f1[i] = (f1[i] + res[i][k] * (i64)f[k]) % MOD; int r = 0; for( int i = 0; i < N; i += k ) r = ( r + f1[i] ) % MOD; return r; } int main() { double cl = clock(); while( scanf("%d %d", &n, &k) == 2 && n ) { printf("%d\n", solve()); } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }J,尼玛扑克的范围不一定啊。那就是说。。。要算很大的数了。。。暴力不行了。。用了fft。没看懂这个神奇的算法,。。。
#include<cmath> #include<cstring> #include<cstdio> #include<cassert> #include<algorithm> #include <ctime> #define rept(i,n) for(int i = 0; i < (n); i++) #define PI 3.14159265358979323846264338327950288 using namespace std; struct pdd { double x,y; pdd():x(0),y(0) {} pdd(double _x,double _y):x(_x),y(_y) {} }; inline pdd operator +(const pdd &a,const pdd &b) { return pdd(a.x+b.x,a.y+b.y); } inline pdd operator -(const pdd &a,const pdd &b) { return pdd(a.x-b.x,a.y-b.y); } inline pdd operator *(const pdd &a,const pdd &b) { return pdd(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x); } inline pdd operator /(const pdd &a,const double &b) { return pdd(a.x/b,a.y/b); } inline pdd conj(const pdd &a) { return pdd(a.x,-a.y); } const int maxn = 300000; struct FFT { int n; int SN; int rv[1<<18]; pdd w[1<<18]; void fft(pdd *a, bool inv) { int cc=0; rept(i,30) if (n&1<<i) cc=i; if (cc!=SN) { SN=cc; rv[0]=0; rv[1]=1; for(int st = 1; st <= SN-1; st++) { int k=1<<st; rept(i,k) { rv[i+(1<<st)]=rv[i]*2+1; rv[i]*=2; } } rept(i,1<<SN) w[i]=pdd(cos(2.0*PI*i/n),sin(2.0*PI*i/n)); } rept(i,n) if (rv[i]<=i) swap(a[i],a[rv[i]]); for (int st=2;st<=n;st*=2) { int d=n/st,o=st/2; for (int i=0;i<n;i+=st) { for (int j=0;j<o;++j) { pdd u=a[i+j],v=a[i+j+o]*(inv?conj(w[j*d]):w[j*d]); a[i+j]=u+v; a[i+j+o]=u-v; } } } if (inv) rept(i,n) a[i]=a[i]/n; } void Multi(long long* A, int NA, long long* B, int NB, long long* C, pdd* tA, pdd* tB) { SN = -1; n = 1; while(n < NA + NB) n *= 2; n *= 2; for(int i = 0; i < n; i++) { tA[i] = (i < NA ? pdd(A[i], 0) : pdd(0, 0)); tB[i] = (i < NB ? pdd(B[i], 0) : pdd(0, 0)); } fft(tA, 0); fft(tB, 0); for(int i = 0; i < n; i++) tA[i] = tA[i] * tB[i]; fft(tA, 1); for(int i = 0; i < n; i++) C[i] = (long long)(tA[i].x + 0.5); } }; FFT fft; int vis[100000]; void sieve(int n) { int m = (int)sqrt(n+0.5); memset(vis, 0, sizeof(vis)); for(int i = 2; i <= m; i++) if(!vis[i]) for(int j = i*i; j <= n; j+=i) vis[j] = 1; } long long poly[7][maxn]; pdd tA[maxn], tB[maxn]; int getSuit(char s) { if(s == 'S') return 0; if(s == 'H') return 1; if(s == 'C') return 2; if(s == 'D') return 3; } int main() { int a, p, c; double cl = clock(); sieve(50000); while(scanf("%d%d%d", &a, &p, &c) == 3 && p) { for(int i = 0; i < p; i++) { int v = 0; if(i >= 4 && vis[i]) v = 1; poly[0][i] = poly[1][i] = poly[2][i] = poly[3][i] = v; } for(int i = 0; i < c; i++) { char card[9]; scanf("%s", card); int len = strlen(card); int suit = getSuit(card[len-1]); int rank; card[len-1] = '\0'; sscanf(card, "%d", &rank); assert(rank >= 4 && vis[rank]); poly[suit][rank] = 0; } fft.Multi(poly[0], p, poly[1], p, poly[4], tA, tB); fft.Multi(poly[2], p, poly[3], p, poly[5], tA, tB); fft.Multi(poly[4], p, poly[5], p, poly[6], tA, tB); for(int i = a; i <= p; i++) printf("%d\n", poly[6][i] % 1000000); // linuxϸijÉ%lld printf("\n"); } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }K,线段树傻逼题,没时间呢。其实我线段树一点都不熟。。但是知道怎么做。。
#include <set> #include <map> #include <list> #include <cmath> #include <ctime> #include <deque> #include <queue> #include <stack> #include <cctype> #include <cstdio> #include <string> #include <vector> #include <cassert> #include <cstdlib> #include <cstring> #include <sstream> #include <iostream> #include <algorithm> using namespace std; const int NN = 1 << 18; const int inf = 1000000000; int n, q, A[NN], pos[NN], test, T[NN], C[50], update[NN]; void makeTree( int idx, int low, int high ) { if( low == high ) { T[idx] = A[low]; pos[low] = idx; update[idx] = 0; return; } int mid = (low + high) >> 1; makeTree( idx << 1, low, mid ); makeTree( ( idx << 1 ) | 1, mid + 1, high ); T[idx] = min( T[idx << 1], T[(idx << 1 ) | 1] ); } int queryTree( int idx, int low, int high, int x, int y ) { if( x <= low && high <= y ) return T[idx]; int res = inf, mid = (low + high) >> 1; if( x <= mid ) res = queryTree( idx << 1, low, mid, x, y ); if( y > mid ) res = min( res, queryTree( ( idx << 1 ) | 1, mid + 1, high, x, y ) ); return res; } int main() { double cl = clock(); while( scanf("%d %d", &n, &q) == 2 && n ) { for( int i = 1; i <= n; i++ ) scanf("%d", &A[i]); makeTree( 1, 1, n ); test = 0; while( q-- ) { char a[40]; scanf("%s", a); if( a[0] == 'q' ) { int x, y; sscanf( a + 6, "%d , %d", &x, &y ); printf("%d\n", queryTree( 1, 1, n, x, y )); } else { char *p = strtok( a + 6, "," ); int x = 0; while( p ) { sscanf( p, "%d", &C[x] ); p = strtok( NULL, "," ); x++; } int s = T[ pos[ C[0] ] ]; for( int i = 1; i < x; i++ ) T[ pos[ C[i-1] ] ] = T[ pos[ C[i] ] ]; T[ pos[ C[x - 1] ] ] = s; ++test; queue <int> Q; for( int i = 0; i < x; i++ ) { int idx = pos[ C[i] ] >> 1; if( update[idx] < test ) { update[idx] = test; Q.push( idx ); } } while( !Q.empty() ) { int idx = Q.front(); Q.pop(); T[idx] = min( T[idx << 1], T[(idx << 1 ) | 1] ); if( idx > 1 ) { idx >>= 1; if( update[idx] < test ) { update[idx] = test; Q.push( idx ); } } } } } } cl = clock() - cl; fprintf(stderr, "Total Execution Time = %lf seconds\n", cl / CLOCKS_PER_SEC); return 0; }
学姐告诉我被虐是很正常的,要有一个良好的心态去对待各种比赛。
相关文章推荐
- 2011年百度之星程序设计大赛初赛B
- 湖南省第六届 中信软件教育杯 大学生程序设计大赛试题 第一题 汽水瓶
- 第九届湖南省大学生程序设计大赛
- “铁道社杯”湖南省第三届大学生程序设计大赛试题 -------苏东坡的拷问
- 2013年湖南省程序设计大赛 A 近似回文词
- 2012年湖南省第八届程序设计大赛 I Collecting Coins(dfs+bfs)
- 2013年湖南省第九届程序设计大赛 H 高桥和低桥 (线段树+二分)
- 2013年湖南省第九届程序设计大赛 F Funny Car Racing(最短路)
- 费尔马大定理搞笑版 (湖南省第九届大学生计算机程序设计大赛)
- 湖南省第九届程序设计大赛:字符识别?
- 2011年“中兴捧月”杯校园程序设计大赛(第三届)
- 湖南省第六届大学生程序设计大赛原题 F Biggest Number (UVA1182)
- 2011年湖南省第七届大学生计算机程序设计竞赛,E题,盒子游戏
- csu 1503: 点弧之间的距离-湖南省第十届大学生计算机程序设计大赛
- 2013年湖南省第九届程序设计大赛 J 搞笑版费马大定理
- 2017年中国大学生程序设计竞赛-中南地区赛暨第八届湘潭市大学生计算机程序设计大赛题解&源码(A.高斯消元,D,模拟,E,前缀和,F,LCS,H,Prim算法,I,胡搞,J,树状数组)
- HDU1219-1226(杭州电子科技大学第三届程序设计大赛+部分题解)
- 湖南省第八届大学生程序设计大赛原题 D
- 湖南省第六届程序设计大赛D(台球碰撞)
- 湖南省第十一届大学生计算机程序设计竞赛 部分题解 待续