Tink off Challenge Final Round 2017
A:热手题
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <map> 9 #include <stack> 10 #include <set> 11 #include <vector> 12 #include <queue> 13 #include <time.h> 14 #define eps 1e-7 15 #define INF 0x3f3f3f3f 16 #define MOD 1000000007 17 #define rep0(j,n) for(int j=0;j<n;++j) 18 #define rep1(j,n) for(int j=1;j<=n;++j) 19 #define pb push_back 20 #define set0(n) memset(n,0,sizeof(n)) 21 #define ll long long 22 #define ull unsigned long long 23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt) 24 #define max(a,b) (a>b?a:b) 25 #define min(a,b) (a<b?a:b) 26 #define print_runtime printf("Running time:%.3lfs\n",double(clock())/1000.0) 27 #define TO(j) printf(#j": %d\n",j); 28 //#define OJ 29 using namespace std; 30 const int MAXINT = 100010; 31 const int MAXNODE = 100010; 32 const int MAXEDGE = 2*MAXNODE; 33 char BUF,*buf; 34 int read(){ 35 char c=getchar();int f=1,x=0; 36 while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} 37 while(isdigit(c)){x=x*10+c-'0';c=getchar();} 38 return f*x; 39 } 40 char get_ch(){ 41 char c=getchar(); 42 while(!isalpha(c)) c=getchar(); 43 return c; 44 } 45 //------------------- Head Files ----------------------// 46 47 int a,b,c,n,t,ans; 48 void get_input(); 49 void work(); 50 int main() { 51 get_input(); 52 work(); 53 return 0; 54 } 55 void work(){ 56 printf("%d\n",ans); 57 } 58 void get_input(){ 59 a=read();b=read();c=read(); 60 n=read(); 61 rep0(i,n){ 62 t=read(); 63 if(t>b&&t<c) ans++; 64 } 65 }
B:初中数学
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <map> 9 #include <stack> 10 #include <set> 11 #include <vector> 12 #include <queue> 13 #include <time.h> 14 #define eps 1e-7 15 #define INF 0x3f3f3f3f 16 #define MOD 1000000007 17 #define rep0(j,n) for(int j=0;j<n;++j) 18 #define rep1(j,n) for(int j=1;j<=n;++j) 19 #define pb push_back 20 #define set0(n) memset(n,0,sizeof(n)) 21 #define ll long long 22 #define ull unsigned long long 23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt) 24 #define max(a,b) (a>b?a:b) 25 #define min(a,b) (a<b?a:b) 26 #define print_runtime printf("Running time:%.3lfs\n",double(clock())/1000.0) 27 #define TO(j) printf(#j": %d\n",j); 28 //#define OJ 29 using namespace std; 30 const int MAXINT = 100010; 31 const int MAXNODE = 100010; 32 const int MAXEDGE = 2*MAXNODE; 33 char BUF,*buf; 34 int read(){ 35 char c=getchar();int f=1,x=0; 36 while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} 37 while(isdigit(c)){x=x*10+c-'0';c=getchar();} 38 return f*x; 39 } 40 char get_ch(){ 41 char c=getchar(); 42 while(!isalpha(c)) c=getchar(); 43 return c; 44 } 45 //------------------- Head Files ----------------------// 46 47 int n,h; 48 void get_input(); 49 void work(); 50 int main() { 51 get_input(); 52 work(); 53 return 0; 54 } 55 void work(){ 56 double s=0.5*h,ans = s/n; 57 for(int i=1;i<n;i++){ 58 printf("%.12lf\n",h*sqrt(i*ans/s)); 59 } 60 } 61 void get_input(){ 62 n=read();h=read(); 63 }
C:我讨厌游戏题
首先双方都只会选对他来说最优的那些字母来放置
为了方便,我们把希望字典序大的一方称为A,另一方为B
当A的最大字符比B的最小字符要大的时候,双方都会把对自己最优往前放
而当A的最大字符比B的最小字符要小的时候,双方会尽量把对自己不优的字符往后放,逼迫对方把不优的字符往前放
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <map> 9 #include <stack> 10 #include <set> 11 #include <vector> 12 #include <queue> 13 #include <time.h> 14 #define eps 1e-7 15 #define INF 0x3f3f3f3f 16 #define MOD 1000000007 17 #define rep0(j,n) for(int j=0;j<n;++j) 18 #define rep1(j,n) for(int j=1;j<=n;++j) 19 #define pb push_back 20 #define set0(n) memset(n,0,sizeof(n)) 21 #define ll long long 22 #define ull unsigned long long 23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt) 24 #define max(a,b) (a>b?a:b) 25 #define min(a,b) (a<b?a:b) 26 #define print_runtime printf("Running time:%.3lfs\n",double(clock())/1000.0) 27 #define TO(j) printf(#j": %d\n",j); 28 //#define OJ 29 using namespace std; 30 const int MAXINT = 300010; 31 const int MAXNODE = 100010; 32 const int MAXEDGE = 2*MAXNODE; 33 char BUF,*buf; 34 int read(){ 35 char c=getchar();int f=1,x=0; 36 while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} 37 while(isdigit(c)){x=x*10+c-'0';c=getchar();} 38 return f*x; 39 } 40 char get_ch(){ 41 char c=getchar(); 42 while(!isalpha(c)) c=getchar(); 43 return c; 44 } 45 //------------------- Head Files ----------------------// 46 47 char s[2][MAXINT],ans[MAXINT]; 48 int cnt[2][26],p1,p2,c1,c2,l; 49 void get_input(); 50 void work(); 51 int main() { 52 get_input(); 53 work(); 54 return 0; 55 } 56 void work(){ 57 p1=0;p2=0; 58 rep0(i,l){ 59 if(s[1][p2]<=s[0][p1]){ 60 for(int j=l-1;j>=i;j--){ 61 if(((l-1-j)^i)&1){ 62 ans[j]=s[1][--c2]; 63 }else{ 64 ans[j]=s[0][--c1]; 65 } 66 } 67 break; 68 } 69 if(i&1){//big 70 ans[i]=s[1][p2++]; 71 }else{ 72 ans[i]=s[0][p1++]; 73 } 74 } 75 ans[l]='\0'; 76 printf("%s\n",ans); 77 } 78 void get_input(){ 79 rep0(i,2){ 80 scanf("%s",s[i]); 81 l = strlen(s[i]); 82 } 83 c1 = l/2+l%2; 84 c2 = l/2; 85 sort(s[0],s[0]+l); 86 sort(s[1],s[1]+l,greater<char>() ); 87 }
D:这大概是最难的一题。。。
首先把每个点本身加入自己的临接表里,然后我们声称所有的有着相同临接表的点的权值都相同,显然这样不会使情况更坏
而且显然临接表不同的点权值一定不同
然后我们把权值相同的点缩成一个点,重新构图,我们发现如果一个点的度数大于2那肯定不存在一个合法的解,而且如果这些点成环了也不存在合法的解,最后只剩下一条链的情况,直接一路标下来即可
注意哈希冲突,没有stl这道题不是要写死
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <map> 9 #include <stack> 10 #include <set> 11 #include <vector> 12 #include <queue> 13 #include <time.h> 14 #define eps 1e-7 15 #define INF 0x3f3f3f3f 16 #define MOD 1000000007 17 #define rep0(j,n) for(int j=0;j<n;++j) 18 #define rep1(j,n) for(int j=1;j<=n;++j) 19 #define pb push_back 20 #define set0(n) memset(n,0,sizeof(n)) 21 #define ll long long 22 #define ull unsigned long long 23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt) 24 #define max(a,b) (a>b?a:b) 25 #define min(a,b) (a<b?a:b) 26 #define print_runtime printf("Running time:%.3lfs\n",double(clock())/1000.0) 27 #define TO(j) printf(#j": %d\n",j); 28 //#define OJ 29 using namespace std; 30 const int MAXINT = 100010; 31 const int MAXNODE = 300010; 32 const int MAXEDGE = 2 * MAXNODE; 33 char BUF, *buf; 34 int read() { 35 char c = getchar(); int f = 1, x = 0; 36 while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();} 37 while (isdigit(c)) {x = x * 10 + c - '0'; c = getchar();} 38 return f * x; 39 } 40 char get_ch() { 41 char c = getchar(); 42 while (!isalpha(c)) c = getchar(); 43 return c; 44 } 45 //------------------- Head Files ----------------------// 46 int cnt, n, m,cnt_e; 47 vector<int> e[MAXNODE], ne[MAXNODE]; 48 map<pair<int,int>, vector<int> > t; 49 map<pair<int,int>, int> ys; 50 set<pair<int,int> > es; 51 int d[MAXNODE],ans[MAXNODE],cl[MAXNODE]; 52 pair<int,int> hs[MAXNODE]; 53 void dfs(int p,int fa){ 54 for(auto i = ne[p].begin();i!=ne[p].end();i++){ 55 if(*i==fa) continue; 56 cl[*i]=cl[p]+1; 57 dfs(*i,p); 58 } 59 } 60 void get_input(); 61 void work(); 62 int main() { 63 get_input(); 64 work(); 65 return 0; 66 } 67 void work() { 68 for (auto i = t.begin(); i != t.end(); i++) { 69 ys[i->first] = ++cnt; 70 } 71 rep1(i, n) { 72 for (auto j = e[i].begin(); j != e[i].end(); j++) { 73 int u = ys[hs[i]],v=ys[hs[*j]]; 74 if(u==v) continue; 75 if(u>v) swap(u,v); 76 if(es.count(make_pair(u,v))) continue; 77 ne[u].push_back(v); 78 ne[v].push_back(u); 79 d[u]++; 80 d[v]++; 81 if(d[u]>2||d[v]>2) { 82 printf("NO\n"); 83 return; 84 } 85 cnt_e++; 86 es.insert(make_pair(u,v)); 87 } 88 } 89 if(cnt_e==cnt) { 90 printf("NO\n"); 91 return; 92 } 93 rep1(i,cnt) cl[i]=1; 94 rep1(i,cnt) if(d[i]==1) {dfs(i,0); break;} 95 for (auto i = t.begin(); i != t.end(); i++) { 96 int x = cl[ys[i->first]]; 97 for(auto j = i->second.begin();j!=i->second.end();j++){ 98 ans[*j]=x; 99 } 100 } 101 printf("YES\n"); 102 rep1(i,n) printf("%d ",ans[i]); 103 putchar('\n'); 104 } 105 void get_input() { 106 n = read(); m = read(); 107 rep0(i, m) { 108 int u = read(), v = read(); 109 e[u].push_back(v); 110 e[v].push_back(u); 111 } 112 rep1(i, n) { 113 e[i].push_back(i); 114 sort(e[i].begin(), e[i].end()); 115 int v = 0,v2 = 0; 116 for (auto j = e[i].begin(); j != e[i].end(); j++) { 117 v = ((ll)v * 19260817ll + *j) % MOD; 118 v2 = ((ll)v2 * 171ll + *j) % MOD; 119 } 120 t[make_pair(v,v2)].push_back(i); 121 hs[i] = make_pair(v,v2); 122 } 123 }
E:有一个很有趣的性质
如果剩下的胡萝卜个数是偶数,那么最终的答案是中间两个的较大值
如果剩下的胡萝卜个数是奇数,那么如果最中央胡萝卜比它两侧的胡萝卜都要小,最终答案是中央胡萝卜,否则是中间三个的中间数
有了这个直接维护两个堆就可以了,注意最后一个胡萝卜需要特判
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <map> 9 #include <stack> 10 #include <set> 11 #include <vector> 12 #include <queue> 13 #include <time.h> 14 #define eps 1e-7 15 #define INF 0x3f3f3f3f 16 #define MOD 1000000007 17 #define rep0(j,n) for(int j=0;j<n;++j) 18 #define rep1(j,n) for(int j=1;j<=n;++j) 19 #define pb push_back 20 #define set0(n) memset(n,0,sizeof(n)) 21 #define ll long long 22 #define ull unsigned long long 23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt) 24 #define print_runtime printf("Running time:%.3lfs\n",double(clock())/1000.0) 25 #define TO(j) printf(#j": %d\n",j); 26 //#define OJ 27 using namespace std; 28 const int MAXINT = 300010; 29 const int MAXNODE = 100010; 30 const int MAXEDGE = 2*MAXNODE; 31 char BUF,*buf; 32 int read(){ 33 char c=getchar();int f=1,x=0; 34 while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} 35 while(isdigit(c)){x=x*10+c-'0';c=getchar();} 36 return f*x; 37 } 38 char get_ch(){ 39 char c=getchar(); 40 while(!isalpha(c)) c=getchar(); 41 return c; 42 } 43 //------------------- Head Files ----------------------// 44 int n,a[MAXINT],m[MAXINT]; 45 priority_queue<int> even,odd; 46 void get_input(); 47 void work(); 48 int main() { 49 get_input(); 50 work(); 51 return 0; 52 } 53 void work(){ 54 if(n==1){ 55 printf("%d\n",a[1]); 56 return ; 57 } 58 if(n&1) even.push(a[n/2+1]); 59 rep0(i,n){ 60 if((n-i)&1){ 61 if(i==n-1){ 62 int ans=0; 63 rep1(i,n) ans=max(ans,a[i]); 64 printf("%d ",ans); 65 continue; 66 } 67 if(n&1){ 68 odd.push(m[n/2+1+i/2]); 69 odd.push(m[n/2+1-i/2]); 70 }else{ 71 odd.push(m[n/2+1+i/2]); 72 odd.push(m[n/2-i/2]); 73 } 74 printf("%d ",odd.top()); 75 }else { 76 if(n&1){ 77 even.push(a[n/2+1-(i+1)/2]); 78 even.push(a[n/2+1+(i+1)/2]); 79 }else{ 80 even.push(a[n/2-i/2]); 81 even.push(a[n/2+1+i/2]); 82 } 83 printf("%d ",even.top()); 84 } 85 } 86 putchar('\n'); 87 } 88 void get_input(){ 89 n=read(); 90 rep1(i,n) a[i]=read(); 91 m[1]=a[1];m[n]=a[n]; 92 for(int i=2;i<=n-1;i++){ 93 if(a[i]>a[i+1]&&a[i]>a[i-1]) m[i] = max(a[i-1],a[i+1]); 94 else m[i]=a[i]; 95 } 96 }
F:这题真是没话说,接近O(60*nlogn)是怎么过去的
发现这个可以很容易的用线段树维护,只需要维护每个数字在这里面的倍数即可(在十位数上出现即为10,百位即为100)
然后打tag的时候暴力O(10)修改
我还傻乎乎的加了一堆乱七八糟的东西,尝试了一下利用区间覆盖会导致的合并元素段,结果反而T了
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <algorithm> 5 #include <string> 6 #include <cstring> 7 #include <cmath> 8 #include <map> 9 #include <stack> 10 #include <set> 11 #include <vector> 12 #include <queue> 13 #include <time.h> 14 #define eps 1e-7 15 #define INF 0x3f3f3f3f 16 #define MOD 1000000007 17 #define rep0(j,n) for(int j=0;j<n;++j) 18 #define rep1(j,n) for(int j=1;j<=n;++j) 19 #define pb push_back 20 #define set0(n) memset(n,0,sizeof(n)) 21 #define ll long long 22 #define ull unsigned long long 23 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt) 24 #define print_runtime printf("Running time:%.3lfs\n",double(clock())/1000.0) 25 #define TO(j) printf(#j": %d\n",j); 26 //#define OJ 27 using namespace std; 28 const int MAXINT = 100010; 29 const int MAXNODE = 100010; 30 const int MAXEDGE = 2 * MAXNODE; 31 char BUF, *buf; 32 int read() { 33 char c = getchar(); int f = 1, x = 0; 34 while (!isdigit(c)) { if (c == '-') f = -1; c = getchar(); } 35 while (isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } 36 return f * x; 37 } 38 char get_ch() { 39 char c = getchar(); 40 while (!isalpha(c)) c = getchar(); 41 return c; 42 } 43 //------------------- Head Files ----------------------// 44 int cnt, a[MAXINT], n, q; 45 struct node { 46 node *l, *r; 47 int lb, rb, tag[10], mid, cnt; 48 ll mul[10], sum; 49 void pushup() { 50 rep0(i, 10) mul[i] = l->mul[i] + r->mul[i]; 51 sum = l->sum + r->sum; 52 } 53 void addtag(int from, int to) { 54 tag[from] = to; 55 pushdown(); 56 } 57 void pushdown() { 58 ll ns[10] = {}; 59 if (rb - lb >1) { 60 rep0(i, 10) l->tag[i] = tag[l->tag[i]]; 61 rep0(i, 10) r->tag[i] = tag[r->tag[i]]; 62 } 63 rep0(i, 10) ns[tag[i]] += mul[i]; 64 rep0(i, 10) mul[i] = ns[i]; 65 sum = 0; 66 rep0(i, 10) sum += i * mul[i]; 67 rep0(i, 10) tag[i] = i; 68 } 69 }; 70 struct Segtree { 71 node mp[MAXINT * 4]; 72 int cnt; 73 node *root; 74 Segtree() { 75 cnt = 0; 76 } 77 node *newnode(int lb, int rb) { 78 node *p = &mp[cnt++]; 79 p->lb = lb; 80 p->rb = rb; 81 p->mid = (lb + rb) / 2; 82 p->sum = 0; 83 rep0(i, 10) p->tag[i] = i; 84 rep0(i, 10) p->mul[i] = 0; 85 return p; 86 } 87 void build(int l, int r) { 88 build(l, r, root); 89 } 90 void build(int l, int r, node *&p) { 91 p = newnode(l, r); 92 if (r - l > 1) { 93 build(l, p->mid, p->l); 94 build(p->mid, r, p->r); 95 p->pushup(); 96 } 97 else { 98 int t = 1; 99 while (a[l]) { 100 p->mul[a[l] % 10] += t; 101 a[l] /= 10; 102 t = t * 10; 103 } 104 rep0(i, 10) p->sum += i * p->mul[i]; 105 } 106 } 107 void modify(int l, int r, int from, int to) { 108 modify(l, r, from, to, root); 109 } 110 void modify(int l, int r, int from, int to, node *p) { 111 p->pushdown(); 112 if (p->lb >= r || p->rb <= l) return; 113 if (p->lb >= l && p->rb <= r) { 114 p->addtag(from, to); 115 return; 116 } 117 modify(l, r, from, to, p->l); 118 modify(l, r, from, to, p->r); 119 p->pushup(); 120 } 121 ll query(int l, int r) { 122 return query(l, r, root); 123 } 124 ll query(int l, int r, node *p) { 125 p->pushdown(); 126 if (p->lb >= r || p->rb <= l) return 0; 127 if (p->lb >= l && p->rb <= r) return p->sum; 128 return query(l, r, p->l) + query(l, r, p->r); 129 } 130 } seg; 131 void get_input(); 132 void work(); 133 int main() { 134 get_input(); 135 work(); 136 return 0; 137 } 138 void work() { 139 while (q--) { 140 int op = read(); 141 if (op == 1) { 142 int l = read(), r = read(), from = read(), to = read(); 143 if (from == to) continue; 144 seg.modify(l, r + 1, from, to); 145 } 146 else { 147 int l = read(), r = read(); 148 printf("%lld\n", seg.query(l, r + 1)); 149 } 150 } 151 } 152 void get_input() { 153 n = read(); q = read(); 154 rep1(i, n) a[i] = read(); 155 seg.build(1, n + 1); 156 } 157 /* 158 5 5 159 38 43 4 12 70 160 1 1 3 4 8 161 2 2 4 162 1 4 5 0 8 163 1 2 5 8 7 164 2 1 5 165 */
许愿弥生改二