Problem A: Assignment Algorithm
Time limit: 1 s
Memory limit: 512 MiB
A low-budget airline is designing a sophisticated algorithm that will assign more desirable seats to
passengers who buy tickets earlier. Their airplane has r rows of seats, where r is an even integer. There
are also 3 exit rows in the airplane; those rows do not contain any seats but only provide access to the
emergency exits. One exit row is in the very front of the airplane (before the first row of seats), one in
the very back (behind the last row of seats) and one right in the middle. The rows are numbered with
integers 1 through r + 3 with row numbers increasing from the front to the back of the airplane. Rows
numbered 1, r/2 + 2 and r + 3 are exit rows while all the other rows are seat rows.
The seating configuration is “3–3–3” — each seat row contains three groups of three seats with the
passenger aisles between the groups. Seats in the same row are denoted with consecutive letters left to
right corresponding to the pattern “ ABC.DEF.GHI ”.
When a passenger purchases a ticket, she is assigned a seat according to the following rules:
1. If there is an empty seat in a row directly after an exit row, all other rows are ignored in the
following step (but they are not ignored when balancing the airplane in the last step).
2. First, we select a seat row with the largest number of empty seats. If there are multiple such rows,
we select the one closest to an exit row (distance between rows a and b is simply | a − b | ). If there
are still multiple such rows, we select the one with the lowest number.
3. Now, we consider empty seats in the selected row and select one with the highest priority. Seat
priorities, from highest to lowest are as follows:
(a) Aisle seats in the middle group ( D or F ).
(b) Aisle seats in the first and third group ( C or G ).
(c) Window seats ( A or I ).
(d) Middle seat in the middle group ( E ).
(e) Other middle seats ( B or H ).
If there are two empty seats with the same highest priority, we consider the balance of the entire
airplane. The airplane’s left side contains all seats with letters A , B , C or D , while the right side
contains all seats with letters F , G , H or I . We select an empty seat in the side with more empty
seats. If both sides have the same number of empty seats, we select the seat in the left side of the
airplane.
Some of the airplane’s seats are already reserved (possibly using a completely different procedure from
the one described above). Determine the seats assigned to the next n passengers purchasing a ticket.
Input
The first line contains two integers r and n (2 ≤ r ≤ 50, 1 ≤ n ≤ 26) — the number of seat rows in the
airplane (always an even integer) and the number of new passengers purchasing tickets. The following
r + 3 lines contain the current layout of the airplane. The j-th line contains exactly 11 characters — the
layout of the row j of the airplane. Exit rows and aisles are denoted with the “ . ” characters. The “ # ”
character denotes a reserved seat, while the “ - ” character denotes a seat that is currently empty. You
may assume there will be at least n empty seats in the airplane.
Output
Output r + 3 lines containing the final layout of the airplane. The layout should be exactly the same
as in input with the following exception: the seat assigned to the j-th passenger purchasing a ticket
Page 1 of 16Central Europe Regional Contest
Zagreb, November 1719, 2017
should be denoted with the j-th lowercase letter of the English alphabet.
模拟飞机位置分配,然后有一些规则和选位置的优先权,
1.优先把安全出口的后面两行坐满
2.每次分配先找空位置最多的行数,如果有多个选离安全位置最近的,如果一样近就选
行数小的。
3.选好行数后,对于每行的位置有个优先权限,还要考虑到飞机平衡性。
代码略多,其实可以减少很多但是不愿改了。
1 A 2 3 #include <bits/stdc++.h> 4 #define N 100 5 using namespace std; 6 int n,m; 7 int left1 = 0, right1 = 0; 8 char s[N][12]; 9 int val[N]; 10 int pos = 0; 11 struct Node 12 { 13 int id; 14 int val; 15 int dis; 16 }node[N]; 17 18 bool cmp(Node a, Node b){ 19 if(a.val == b.val){ 20 if(a.dis == b.dis){ 21 return a.id < b.id; 22 } 23 return a.dis < b.dis; 24 } 25 return a.val > b.val; 26 } 27 28 bool cmp1(Node a, Node b){ 29 return a.id < b.id; 30 } 31 32 void change(int x){ 33 if(s[x][4] == '-' || s[x][6] == '-'){ 34 if(s[x][4] == '-' && s[x][6] == '-'){ 35 if(left1 <= right1){ 36 s[x][4] = 'a' + pos++; 37 left1++; 38 }else{ 39 s[x][6] = 'a' + pos++; 40 right1++; 41 } 42 }else{ 43 if(s[x][4] == '-'){ 44 s[x][4] = 'a' + pos++; 45 left1++; 46 }else{ 47 s[x][6] = 'a' + pos++; 48 right1++; 49 } 50 } 51 }else if(s[x][2] == '-' || s[x][8] == '-'){ 52 if(s[x][2] == '-' && s[x][8] == '-'){ 53 if(left1 <= right1){ 54 s[x][2] = 'a' + pos++; 55 left1++; 56 }else{ 57 s[x][8] = 'a' + pos++; 58 right1++; 59 } 60 }else{ 61 if(s[x][2] == '-'){ 62 s[x][2] = 'a' + pos++; 63 left1++; 64 }else{ 65 s[x][8] = 'a' + pos++; 66 right1++; 67 } 68 } 69 }else if(s[x][0] == '-' || s[x][10] == '-'){ 70 if(s[x][0] == '-' && s[x][10] == '-'){ 71 if(left1 <= right1){ 72 s[x][0] = 'a' + pos++; 73 left1++; 74 }else{ 75 s[x][10] = 'a' + pos++; 76 right1++; 77 } 78 }else{ 79 if(s[x][0] == '-'){ 80 s[x][0] = 'a' + pos++; 81 left1++; 82 }else{ 83 s[x][10] = 'a' + pos++; 84 right1++; 85 } 86 } 87 }else if(s[x][5] == '-'){ 88 s[x][5] = 'a' + pos++; 89 }else{ 90 if(s[x][1] == '-' && s[x][9] == '-'){ 91 if(left1 <= right1){ 92 s[x][1] = 'a' + pos++; 93 left1++; 94 }else{ 95 s[x][9] = 'a' + pos++; 96 right1++; 97 } 98 }else{ 99 if(s[x][1] == '-'){ 100 s[x][1] = 'a' + pos++; 101 left1++; 102 }else{ 103 s[x][9] = 'a' + pos++; 104 right1++; 105 } 106 } 107 } 108 } 109 110 111 int main(){ 112 scanf("%d%d", &n, &m); 113 for(int i = 0; i < n+3; i++ ){ 114 int ans = 0; 115 cin >> s[i]; 116 for(int j = 0; j < 11; j++ ){ 117 if(s[i][j] == '-') 118 ans++; 119 else if(s[i][j] == '#'){ 120 if(j < 5) 121 left1 ++; 122 else if(j > 5) 123 right1 ++; 124 } 125 } 126 node[i].id = i; 127 node[i].val = ans; 128 node[i].dis = min(abs(i), min(abs((n>>1)+1-i), abs(n+2-i))); 129 } 130 131 int ans = node[1].val + node[(n>>1)+2].val; 132 while(ans-- && m--){ 133 if(node[1].val >= node[(n>>1)+2].val){ 134 node[1].val--; 135 change(1); 136 }else{ 137 node[(n>>1)+2].val--; 138 change((n>>1)+2); 139 } 140 } 141 142 while(m--){ 143 sort(node, node+n+3, cmp); 144 node[0].val--; 145 change(node[0].id); 146 } 147 148 sort(node, node+n+3,cmp1); 149 for(int i = 0; i < n+3; i++){ 150 for(int j = 0; j < 11; j++){ 151 cout<<s[i][j]; 152 } 153 cout << endl; 154 } 155 cout << endl; 156 return 0; 157 }
Problem F: Faulty Factorial
Time limit: 3 s
Memory limit: 512 MiB
The factorial of a natural number is the product of all positive integers less than or equal to it. For
example, the factorial of 4 is 1 · 2 · 3 · 4 = 24. A faulty factorial of length n is similar to the factorial of n,
but it contains a fault: one of the integers is strictly smaller than what it should be (but still at least 1).
For example, 1 · 2 · 2 · 4 = 16 is a faulty factorial of length 4.
Given the length n, a prime modulus p and a target remainder r, find some faulty factorial of length n
that gives the remainder r when divided by p.
Input
The first line contains three integers n, p and r (2 ≤ n ≤ 10 18 , 2 ≤ p < 10 7 , 0 ≤ r < p) — the length of
the faulty factorial, the prime modulus and the target remainder as described in the problem statement.
Output
If there is no faulty factorial satisfying the requirements output “-1 -1”. Otherwise, output two integers
— the index k of the fault (2 ≤ k ≤ n) and the value v at that index (1 ≤ v < k). If there are multiple
solutions, output any of them.
Examples
input input
4 5 1 4 127 24
output output
3 2 -1 -1
In the first example, the output describes the faulty factorial 1 · 2 · 2 · 4 = 2 4 ≡ 1 ( mod 5 ) .
分为n==p, n>=2*p, 2*p>n>p , n<p 四种情况讨论
其中n==p使用到了威尔逊定理,且注意, n=p=2,无解
下面是两种解法,第一种是用的线性求逆元, 第二种就是把公式转换了一下。(还是自己太菜)
1 F 2 3 #include <bits/stdc++.h> 4 using namespace std; 5 #define ll long long 6 ll v[10000006],n,p,r; 7 ll quick_pow(ll x,ll y,ll mod){ 8 ll ans=1; 9 while(y){ 10 if(y&1) ans=ans*x%mod; 11 y>>=1; 12 x=x*x%mod; 13 } 14 return ans%mod; 15 } 16 void init(){ 17 v[1]=1; 18 for(ll i=2;i<=p;i++){ 19 v[i]=(p-(p/i))*v[p%i]%p; 20 } 21 } 22 int main(){ 23 scanf("%lld%lld%lld",&n,&p,&r); 24 init(); 25 /*for(int i=1;i<=100;i++){ 26 if(v[i]==0) printf("1 "); 27 //if(m[i]==0) printf(" 1 "); 28 }*/ 29 if(n>=2*p){ 30 if(r==0){ 31 printf("%lld 1 ",p); 32 } 33 else printf("-1 -1 "); 34 } 35 else if(n>=p && r){ 36 ll ans=1; 37 for(int i=1;i<=n;i++){ 38 if(i==p) continue; 39 ans=ans*i%p; 40 } 41 int ok=0; 42 for(ll i=1;i<p;i++){ 43 if(((ans*i)%p)==r){ 44 printf("%lld %lld ",p,i); 45 ok=1; 46 break; 47 } 48 } 49 if(!ok) printf("-1 -1 "); 50 } 51 else if(n>=p && !r){ 52 int ok=0; 53 for(int i=2;i<=n;i++){ 54 if(i!=p){ 55 printf("%d 1 ",i); 56 ok=1; 57 break; 58 } 59 } 60 if(!ok) printf("-1 -1 "); 61 } 62 else if(n<p){ 63 ll ans=1; 64 for(ll i=1;i<=n;i++) 65 ans=ans*i%p; 66 int ok=0; 67 for(ll i=2;i<=n;i++){ 68 ll q=ans*v[i]%p; 69 ll re=r*v[q]%p; 70 if(re<i && re>0){ 71 printf("%lld %lld ",i,re); 72 ok=1; 73 break; 74 } 75 } 76 if(!ok) printf("-1 -1 "); 77 } 78 return 0; 79 } 80 81 82 F 83 84 #include <bits/stdc++.h> 85 86 #define ll long long int 87 88 using namespace std; 89 ll n, p, r; 90 91 ll quick(ll a, ll b){ 92 ll ans = 1; 93 while(b){ 94 if(b&1){ 95 ans = (ans*a)%p; 96 } 97 b >>= 1; 98 a = (a*a)%p; 99 } 100 return ans; 101 } 102 103 int main(){ 104 cin >> n >> p >> r; 105 106 if(n>=2*p){ 107 if(r==0){ 108 cout<<p <<" 1"<<endl; 109 }else{ 110 cout <<"-1 -1"<<endl; 111 } 112 return 0; 113 }else if(n>=p && r){ 114 ll ans=1; 115 for(int i=1;i<=n;i++){ 116 if(i==p) continue; 117 ans=ans*i%p; 118 } 119 for(ll i=1;i<p;i++){ 120 if(((ans*i)%p)==r){ 121 cout <<p<<" "<<i<<endl; 122 return 0; 123 } 124 } 125 cout <<"-1 -1"<<endl; 126 return 0; 127 } 128 else if(n>=p && !r){ 129 int ok=0; 130 for(int i=2;i<=n;i++){ 131 if(i!=p){ 132 cout <<i<<" 1"<<endl; 133 ok=1; 134 break; 135 } 136 } 137 if(!ok) cout <<"-1 -1"<<endl; 138 } 139 else if(n<p){ 140 if (r == 0) cout << -1 << " " << -1 << endl; 141 else{ 142 ll ans=1; 143 for(ll i=1;i<=n;i++) 144 ans=ans*i%p; 145 ans = quick(ans, p-2); 146 for(ll i=2;i<=n;i++){ 147 ll tmp = r*i%p*ans%p; 148 if(tmp<i && tmp>0){ 149 cout <<i<< " " << tmp << endl; 150 return 0; 151 } 152 } 153 cout << -1 << " " << -1 << endl; 154 } 155 } 156 return 0; 157 }
大模拟题,仔细写还是能写出来的。
1 H 2 3 #include <bits/stdc++.h> 4 #define N 50006 5 using namespace std; 6 map<int, string> ito_s; 7 map<string, int> sto_i; 8 set<string> st[N]; 9 vector<int> v[N]; 10 int n, m, all; 11 int val[N]; 12 int vis[N]; 13 int ans = 0; 14 string s; 15 16 void dfs(int x){ 17 for(int i = 0; i < v[x].size(); i++){ 18 dfs(v[x][i]); 19 val[x] += val[v[x][i]]; 20 } 21 } 22 23 void bfs(int x){ 24 if(vis[x]) return; 25 int pos = 0, flag = 0; 26 for(int i = 0; i < v[x].size(); i++){ 27 if(!vis[v[x][i]]){ 28 pos = max(pos, val[v[x][i]]); 29 flag = 1; 30 } 31 } 32 if(!flag) 33 cout <<" "<<ito_s[x]<<" "<<val[x]<<endl; 34 else if(flag && pos < all){ 35 cout <<"+ "<<ito_s[x]<<" "<<val[x]<<endl; 36 }else{ 37 cout <<"- "<<ito_s[x]<<" "<<val[x]<<endl; 38 for(set<string>::iterator it=st[x].begin();it!=st[x].end();it++) 39 bfs(sto_i[*it]); 40 } 41 } 42 43 int main(){ 44 cin >> n; 45 for(int i = 0; i < n; i++){ 46 cin >> s >> m; 47 string ss; 48 sto_i[s] = ++ans; 49 ito_s[ans] = s; 50 val[ans] = m; 51 vis[ans] = 1; 52 ss = s; 53 int j = 1; 54 for(int k = s.length()-1; k >= 0; k --){ 55 string s1; 56 if(s[k] == '/'){ 57 s1 = s.substr(0,k+1); 58 // cout <<s1<<endl; 59 if(!sto_i[s1]){ 60 sto_i[s1] = ++ans; 61 ito_s[ans] = s1; 62 v[ans].push_back(ans-1); 63 st[ans].insert(ss); 64 ss = s1; 65 }else{ 66 v[sto_i[s1]].push_back(ans); 67 st[sto_i[s1]].insert(ss); 68 break; 69 } 70 } 71 } 72 } 73 cin >> all; 74 dfs(sto_i["/"]); 75 bfs(sto_i["/"]); 76 return 0; 77 }
这题想了挺久才想到用边的关系来处理,一直盯着点看去了。
1 J 2 3 #include <bits/stdc++.h> 4 #define N 1000005 5 #define ll long long int 6 using namespace std; 7 typedef pair<int,int>P; 8 map<P, int> mp; 9 map<P, int>::iterator it; 10 int n; 11 int x, y; 12 vector<int> v[N]; 13 int vis[N]; 14 int an[N]; 15 int bn[N], bns = 0; 16 int dfs(int x){ 17 int cnt = 1; 18 vis[x] = 1; 19 for(int i=0; i < v[x].size(); i++){ 20 if(vis[v[x][i]]) 21 continue; 22 int ans = dfs(v[x][i]); 23 int from = min(x, v[x][i]); 24 int to = max(x, v[x][i]); 25 mp[P(from, to)] = ans; 26 cnt += ans; 27 } 28 return cnt; 29 } 30 31 int main(){ 32 scanf("%d" , &n); 33 for(int i = 1; i < n; i ++){ 34 scanf("%d%d", &x, &y); 35 v[x].push_back(y); 36 v[y].push_back(x); 37 // mp[P(x,y)] = 0; 38 } 39 int k = dfs(1); 40 int pos = 0; 41 for(it = mp.begin(); it != mp.end(); it++){ 42 an[pos++] = it->second > (n>>1) ? (n - it->second):it->second; 43 // cout << an[pos-1] << endl; 44 } 45 for(int i = 1; i*i < n; i++){ 46 if(n%(i+1) == 0){ 47 int index1 = 0; 48 int index2 = 0; 49 int sp = n/(i+1); 50 for(int j = 0 ; j < pos; j ++){ 51 if(an[j]%sp == 0) 52 index1++; 53 if(an[j]%(i+1) == 0){ 54 index2++; 55 } 56 } 57 if(index1 == i){ 58 bn[bns++] = i; 59 } 60 if(index2 == sp-1){ 61 bn[bns++] = sp-1; 62 } 63 } 64 } 65 66 67 bn[bns++] = n-1; 68 sort(bn, bn+bns); 69 for(int i = 0; i < bns; i++){ 70 cout << bn[i] << " "; 71 } 72 cout << endl; 73 74 return 0; 75 }