2017 计蒜之道 初赛 第四场
A:商汤科技的安全令牌
商汤科技致力于引领人工智能核心“深度学习”技术突破,构建人工智能、大数据分析行业解决方案。作为一家人工智能公司,用机器自动地解决各类实际问题自然不在话下。近日,商汤科技推出了一套安全令牌,令牌如下图所示:
安全令牌上的小孔有 nn 行 mm 列,不过有些行和有些列已经用导线整体焊接了,共有 kk 根导线。
我们可以在安全令牌上 不重叠 地焊接若干个小芯片,每个芯片需要在相邻(不能斜着相邻,必须平行于行或列)的两个没有被焊接的小孔上固定。不能固定在已经被整体焊接的行或列上。
安全令牌上最多可以放置多少个芯片,就代表了这个安全令牌对应的校验码。当然,由于安全令牌上小孔的密度会很大,是很难目测出对应的校验码的。你作为商汤科技的实习生,需要写出一个程序,能够自动地算出一个给定的安全令牌的校验码。
输入格式
输入第一行三个整数 n,m(1 \le n,m \le 100)n,m(1≤n,m≤100),k(0 \le k \le n + m)k(0≤k≤n+m)。
接下来输入 kk 行,每行输入两个整数 d(0 \le d \le 1)d(0≤d≤1),cc。如果 d = 0d=0,表示第 c(1 \le c \le n)c(1≤c≤n) 行被整体焊接了,如果 d = 1d=1,表示第 c(1 \le c \le m)c(1≤c≤m) 列被整体焊接了。
输出格式
输出安全令牌对应的校验码。
样例输入
4 5 2 0 3 1 4
样例输出
5
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 int main() 7 { 8 int ma[150][150]={0}; 9 int n,m,k; 10 int d,c; 11 int sum=0; 12 scanf("%d %d %d",&n,&m,&k); 13 for(int i=0;i<m+2;i++){ 14 ma[n][i]=1; 15 } 16 for(int i=0;i<n+2;i++){ 17 ma[i][m]=1; 18 } 19 for(int i=0;i<k;i++){ 20 scanf("%d %d",&d,&c); 21 if(d==0){ 22 for(int j=0;j<m;j++){ 23 ma[c-1][j]=1; 24 } 25 }else{ 26 for(int j=0;j<n;j++){ 27 ma[j][c-1]=1; 28 } 29 } 30 } 31 for(int i=0;i<n;i++){ 32 for(int j=0;j<m;j++){ 33 int coux=0; 34 if(ma[i][j]==0){ 35 while(ma[i][j+coux]==0){ 36 coux++; 37 } 38 } 39 int couy=0; 40 if(ma[i][j]==0){ 41 while(ma[i+couy][j]==0){ 42 couy++; 43 } 44 } 45 sum+=(coux*couy/2); 46 for(int o=0;o<couy;o++){ 47 for(int p=0;p<coux;p++){ 48 ma[i+o][j+p]=1; 49 } 50 } 51 } 52 } 53 printf("%d\n",sum); 54 return 0; 55 }
B:商汤科技的行人检测(简单)
商汤科技近日推出的 SenseVideo 能够对视频监控中的对象进行识别与分析,包括行人检测等。在行人检测问题中,最重要的就是对行人移动的检测。由于往往是在视频监控数据中检测行人,我们将图像上的行人抽象为二维平面上若干个的点。那么,行人的移动就相当于二维平面上的变换。
在这道题中,我们将行人的移动过程抽象为 平移,有两个 移动参数:d_xdx 和 d_ydy。每次行人的移动过程会将行人对应的所有点全部平移,对于平移前的点 (x, y)(x,y),平移后的坐标为 (x + d_x, y + d_y)(x+dx,y+dy)。
我们现在已知一个行人对应着 nn 个点,坐标分别为 (x_1,y_1),(x_2,y_2)\ldots (x_n,y_n)(x1,y1),(x2,y2)…(xn,yn),平移后的坐标分别为 (x_1',y_1'),(x_2',y_2')\ldots (x_n',y_n')(x1′,y1′),(x2′,y2′)…(xn′,yn′)。
很显然,通过平移前后的正确坐标,很容易算出行人的移动参数,但问题没有这么简单。由于行人实际的移动并不会完全按照我们预想的方式进行,因此,会有一部分平移后的坐标结果不正确,但可以确保 结果不正确的坐标数量严格不超过一半。
你现在作为商汤科技的实习生,接手了这个有趣的挑战:算出行人的移动参数。如果不存在一组合法的移动参数,则随意输出一组参数;如果有多种合法的移动参数,输出其中任意一组合法的即可。
输入格式
第一行输入一个整数 n(1 \le n \le 10^5)n(1≤n≤105),表示行人抽象出的点数。
接下来 nn 行,每行 44 个 整数。前两个数表示平移前的坐标,后两个数表示平移后的坐标。
坐标范围在 -10^9−109 到 10^9109 之间。
输出格式
一行两个整数,d_xdx 和 d_ydy,表示行人的移动参数。
样例输入
5 0 0 1 1 0 1 1 2 1 0 2 1 1 1 0 0 2 1 1 0
样例输出
1 1
1 #include <iostream> 2 #include <cstdio> 3 4 using namespace std; 5 6 int n; 7 int a[100005][5]={0}; 8 9 int main() 10 { 11 scanf("%d",&n); 12 for(int i=0;i<n;i++){ 13 scanf("%d %d %d %d",&a[i][0],&a[i][1],&a[i][2],&a[i][3]); 14 } 15 for(int i=0;i<n;i++){ 16 if(a[i][4]==0){ 17 int x,y; 18 int num=0; 19 x=a[i][2]-a[i][0]; 20 y=a[i][3]-a[i][1]; 21 for(int j=i;j<n;j++){ 22 if(a[j][0]+x==a[j][2]&&a[j][1]+y==a[j][3]){ 23 num++; 24 a[j][4]=1; 25 if(num>=n/2){ 26 printf("%d %d\n",x,y); 27 return 0; 28 } 29 } 30 } 31 } 32 33 } 34 return 0; 35 }