首页 > 代码库 > Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)

Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)

C. Ray Tracing

 

There are k sensors located in the rectangular room of size n × m meters. The i-th sensor is located at point (xi, yi). All sensors are located at distinct points strictly inside the rectangle.

Opposite corners of the room are located at points (0, 0) and (n, m). Walls of the room are parallel to coordinate axes.

At the moment 0, from the point (0, 0) the laser ray is released in the direction of point (1, 1). The ray travels with a speed of 技术分享 meters per second. Thus, the ray will reach the point (1, 1) in exactly one second after the start.

When the ray meets the wall it‘s reflected by the rule that the angle of incidence is equal to the angle of reflection. If the ray reaches any of the four corners, it immediately stops.

For each sensor you have to determine the first moment of time when the ray will pass through the point where this sensor is located. If the ray will never pass through this point, print  - 1 for such sensors.

Input

The first line of the input contains three integers n, m and k (2 ≤ n, m ≤ 100 000, 1 ≤ k ≤ 100 000) — lengths of the room‘s walls and the number of sensors.

Each of the following k lines contains two integers xi and yi (1 ≤ xi ≤ n - 1, 1 ≤ yi ≤ m - 1) — coordinates of the sensors. It‘s guaranteed that no two sensors are located at the same point.

Output

Print k integers. The i-th of them should be equal to the number of seconds when the ray first passes through the point where the i-th sensor is located, or  - 1 if this will never happen.

Examples
Input
3 3 4
1 1
1 2
2 1
2 2
Output
1
-1
-1
2
Input
3 4 6
1 1
2 1
1 2
2 2
1 3
2 3
Output
1
-1
-1
2
5
-1
Input
7 4 5
1 3
2 2
5 1
5 3
4 3
Output
13
2
9
5
-1
 
题意:给你m*n的矩阵,矩阵里面有一些点,从(0,0)出发以sqrt(2)的速度45度角出发;然后碰到边界会转向,问你到每个点的最小时间是多少。
思路:扩展欧几里的;
可以把原来的矩阵对称再补三块,
技术分享
然后我们可以知道左边红色那点就和右边的那点是对称的,也就是t是相同的那么我们有x1(绿色那边的) = n+(n-x0)%2n=(-x0)%2*n,也就是t%(2*n)= (-x0)  ,那么我们就可以用发现当再次反射时,x的坐标的变化状态和开始的一样,也就是t%2*n = x0;那么同理y的状态,那么每个点都可能有4种状态也就是(t%2*n = x0,t%2*m = y0)
(t%2*n = -x0,t%2*m = -y0);(t%2*n = x0,t%2*m = -y0);(t%2*n = -x0,t%2*m = y0);那么每个都是一个同余方程组,那exgcd()求下,取最小即可。
技术分享
 1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<stdlib.h> 5 #include<string.h> 6 #include<math.h> 7 #include<queue> 8 using namespace std; 9 typedef long long LL;10 pair<LL,LL>exgcd(LL n,LL m);11 LL solve(LL x, LL y,LL n,LL m,LL gc,LL ak);12 LL gcd(LL n,LL m);13 int main(void)14 {15         LL n,m,k;16         while(scanf("%lld %lld %lld",&n,&m,&k)!=EOF)17         {       LL gc = gcd(2*n,2*m); pair<LL,LL>ak = exgcd(2*n,2*m);18                 LL minn = min(solve(0,0,2*n,2*m,gc,ak.first),solve(n,m,2*n,2*m,gc,ak.first));19                 minn = min(minn,solve(0,m,2*n,2*m,gc,ak.first));20                 minn = min(solve(n,0,2*n,2*m,gc,ak.first),minn);//printf("%lld\n",minn);21                 while(k--)22                 {23                         LL x,y;24                         scanf("%lld %lld",&x,&y);25                         LL akk = min(solve(x,y,2*n,2*m,gc,ak.first),solve(2*n-x,2*m-y,2*n,2*m,gc,ak.first));26                         LL bk = min(solve(x,2*m-y,2*n,2*m,gc,ak.first),solve(2*n-x,y,2*n,2*m,gc,ak.first));27                         akk = min(akk,bk);//printf("%lld\n",ak);28                         if(akk==1e18||akk>minn)printf("-1\n");29                         else printf("%lld\n",akk);30                 }31         }32         return 0;33 }34 pair<LL,LL>exgcd(LL n,LL m)35 {36         if(m==0)37                 return make_pair(1,0);38         else39         {40                 pair<LL,LL>ak = exgcd(m,n%m);41                 return make_pair(ak.second,ak.first-(n/m)*ak.second);42         }43 }44 LL solve(LL x, LL y,LL n,LL m,LL gc,LL ak)45 {46         LL cc = n;47         LL c = x-y;48         if(c%gc)return 1e18;49         else50         {51                 c/=gc;52                 n/=gc;53                 m/=gc;54                 LL x0 = (ak*c%m+m)%m;55                 LL lcm = (LL)m*cc;56                 x = x-cc*x0;57                 x = x%lcm+lcm;58                 x%=lcm;59                 if(x==0)x+=lcm;60                 return x;61         }62 }63 LL gcd(LL n,LL m)64 {65         if(m==0)return n;66         else return gcd(m,n%m);67 }
C

 

D. Dense Subsequence
 

You are given a string s, consisting of lowercase English letters, and the integer m.

One should choose some symbols from the given string so that any contiguous subsegment of length m has at least one selected symbol. Note that here we choose positions of symbols, not the symbols themselves.

Then one uses the chosen symbols to form a new string. All symbols from the chosen position should be used, but we are allowed to rearrange them in any order.

Formally, we choose a subsequence of indices 1 ≤ i1 < i2 < ... < it ≤ |s|. The selected sequence must meet the following condition: for every j such that 1 ≤ j ≤ |s| - m + 1, there must be at least one selected index that belongs to the segment [j,  j + m - 1], i.e. there should exist a k from 1 to t, such that j ≤ ik ≤ j + m - 1.

Then we take any permutation p of the selected indices and form a new string sip1sip2... sipt.

Find the lexicographically smallest string, that can be obtained using this procedure.

Input

The first line of the input contains a single integer m (1 ≤ m ≤ 100 000).

The second line contains the string s consisting of lowercase English letters. It is guaranteed that this string is non-empty and its length doesn‘t exceed 100 000. It is also guaranteed that the number m doesn‘t exceed the length of the string s.

Output

Print the single line containing the lexicographically smallest string, that can be obtained using the procedure described above.

Examples
Input
3
cbabc
Output
a
Input
2
abcab
Output
aab
Input
3
bcabcbaccba
Output
aaabb
Note

In the first sample, one can choose the subsequence {3} and form a string "a".

In the second sample, one can choose the subsequence {1, 2, 4} (symbols on this positions are ‘a‘, ‘b‘ and ‘a‘) and rearrange the chosen symbols to form a string "aab".

题意:给出整数m和一个字符串,要求从所给的字符串中选出一些任意顺序组成一个字符串,要求新的字符串在所有符合条件的字符串中字典序最小,如果选择了第i个字符那么在下标在[i+1, i + 1+m]范围内的字符至少被选一个

思路:贪心+单调队列;

我们贪心选取,第一个区间的最小值,区间长度为m那么接下来这个区间每次向右滑一个单位,然后我们只要看下当前区间的一个值是不是被前面区间的最小值,因为如果这个值被选了,无论是不是本区间的最小值,那么本区间就不必再选数了,如果不是,那么找当前区间的最小值选,并且这个最小值要靠后,因为前面的已经保证了,尽量往后选,才能使要选的更少,最小值用单调队列维护。然后最大值,前面所有比他小的都要补上,复杂度O(n);

技术分享
  1 #include<stdio.h>  2 #include<algorithm>  3 #include<iostream>  4 #include<string.h>  5 #include<math.h>  6 #include<queue>  7 #include<stack>  8 #include<set>  9 using namespace std; 10 char str[100005]; 11 int cnt[26]; 12 int ask[100005]; 13 int quq[100005]; 14 set<int>vec; 15 set<int>::iterator it; 16 int main(void) 17 { 18         int n; 19         int i,j; 20         while(scanf("%d",&n)!=EOF) 21         { 22                 vec.clear(); 23                 scanf("%s",str+1); 24                 int l =strlen(str+1); 25                 memset(cnt,0,sizeof(cnt)); 26                 for(i = 1; i <= l; i++) 27                 { 28                         cnt[str[i]-a]++; 29                 } 30                 int head = 1; 31                 int rail = 0; 32                 int cn = 0; 33                 for(i = 1; i <= n; i++) 34                 { 35                         if(head > rail) 36                         { 37                                 quq[++rail] = i; 38                         } 39                         else 40                         { 41                                 while(true) 42                                 { 43                                         if(head > rail) 44                                                 break; 45                                         int id = quq[rail]; 46                                         if(str[id] >= str[i]) 47                                         { 48                                                 rail--; 49                                         } 50                                         else break; 51                                 } 52                                 quq[++rail] = i; 53                         } 54                 } 55                 vec.insert(quq[head]); 56                 for(i = n+1; i <= l; i++) 57                 { 58                         while(true) 59                         { 60                                 if(head>rail) 61                                         break; 62                                 int id = quq[rail]; 63                                 if(str[id] >= str[i]&&!vec.count(id)) 64                                 { 65                                         rail--; 66                                 } 67                                 else break; 68                         } 69                         quq[++rail] = i; 70                         int ic = quq[head]; 71                         while(ic < i-n+1) 72                         { 73                                 head++; 74                                 ic = quq[head]; 75                         } 76                         vec.insert(quq[head]); 77                 } 78                 for(it = vec.begin(); it!=vec.end(); it++) 79                 { 80                         ask[cn++] = str[*it]-a; 81                         cnt[ask[cn-1]]--; 82                 } 83                 sort(ask,ask+cn); 84                 int maxx = ask[cn-1]; 85                 for(i = 0; i < 26; i++) 86                 { 87                         if(i < maxx) 88                         {      //printf("%d\n",cnt[i]); 89                                 while(cnt[i]) 90                                 { 91                                         ask[cn++] = i; 92                                         cnt[i]--; 93                                 } 94                         } 95                 } 96                 sort(ask,ask+cn); 97                 for(i = 0; i <cn; i++) 98                         printf("%c",ask[i]+a); 99                 printf("\n");100         }101         return 0;102 }
D

 

Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined)