A题:
1 second
256 megabytes
standard input
standard output
Someday, Drazil wanted to go on date with Varda. Drazil and Varda live on Cartesian plane. Drazil's home is located in point(0, 0) and Varda's home is located in
point (a, b). In each step, he can move in a unit distance in horizontal or vertical direction. In other words, from position (x, y) he
can go to positions (x + 1, y), (x - 1, y), (x, y + 1) or (x, y - 1).
Unfortunately, Drazil doesn't have sense of direction. So he randomly chooses the direction he will go to in each step. He may accidentally return back to his house during his travel. Drazil may even not notice that he has arrived to (a, b) and
continue travelling.
Luckily, Drazil arrived to the position (a, b) successfully. Drazil said to Varda: "It took me exactly s steps
to travel from my house to yours". But Varda is confused about his words, she is not sure that it is possible to get from (0, 0) to (a, b) in
exactlys steps. Can you find out if it is possible for Varda?
You are given three integers a, b, and s ( - 109 ≤ a, b ≤ 109, 1 ≤ s ≤ 2·109)
in a single line.
If you think Drazil made a mistake and it is impossible to take exactly s steps and get from his home to Varda's home, print "No" (without quotes).
Otherwise, print "Yes".
5 5 11
No
10 15 25
Yes
0 5 1
No
0 0 2
Yes
In fourth sample case one possible route is: .
A题其实是为了上来镇定下,而我一开始还没拿到分,,,连续两次WA,第一次是上来就枚举了所以x,y的情况,主要把他们和0比大小,然后和自身比大小,最后果断跪在第五组数据。。。。
想明白后,,忘记加了abs,,又一次WA,第三次,加上abs,终于过了。。。
也就是说,从(0,0)走,开始走到(x,y)这个点后,可以在这个点的周围乱走,只要乱走的步数为偶数步,那么最终一定可以回到(x,y)的
代码:
# include<cstdio> # include<iostream> # include<cmath> using namespace std; int main(void) { long long x,y; long long step; while ( cin>>x>>y>>step ) { long long ans = step-abs(x)-abs(y); if ( ans < 0 ) { cout<<"No"<<endl; } else { if ( ans%2==0 ) { cout<<"Yes"<<endl; } else { cout<<"No"<<endl; } } } return 0; }
B题:
解题思路:
这道题写个暴力就水过去了,Q神告诉我开1000*1000*10的。。然后,我就照着做了,其实开小点也是可以水过去的。因为n和m都是小于等于100的,那么我们只要寻求最大的流动周期就ok了。。
代码:
# include<cstdio> # include<iostream> # include<cstring> using namespace std; # define MAX 100 int bb[MAX]; int gg[MAX]; int main(void) { int n,m; int b,g; while ( cin>>n>>m ) { memset(bb,0,sizeof(bb)); memset(gg,0,sizeof(gg)); cin>>b; for ( int i = 0;i < b;i++ ) { int t;cin>>t; bb[t] = 1; } cin>>g; for ( int i = 0;i < g;i++ ) { int t;cin>>t; gg[t] = 1; } for ( int i = 0;i <= 10000000;i++ ) { if ( bb[i%n]+gg[i%m] >= 1 ) { bb[i%n] = 1; gg[i%m] = 1; } } int sum1 = 0; int sum2= 0; for ( int i = 0;i < n;i++ ) { if ( bb[i]==1 ) sum1++; } for ( int i = 0;i < m;i++ ) { if ( gg[i]==1 ) sum2++; } if ( sum1==n&&sum2==m ) { cout<<"Yes"<<endl; } else { cout<<"No"<<endl; } } return 0; }
C题:
2 seconds
256 megabytes
standard input
standard output
Drazil is playing a math game with Varda.
Let's define for
positive integer x as a product of factorials of its digits. For example, .
First, they choose a decimal number a consisting of n digits
that contains at least one digit larger than 1. This number may possibly start with leading zeroes. Then they should find maximum positive number x satisfying
following two conditions:
1. x doesn't contain neither digit 0 nor digit 1.
2. = .
Help friends find such number.
The first line contains an integer n (1 ≤ n ≤ 15)
— the number of digits in a.
The second line contains n digits of a. There
is at least one digit in a that is larger than 1. Number a may
possibly contain leading zeroes.
Output a maximum possible integer satisfying the conditions above. There should be no zeroes and ones in this number decimal representation.
4 1234
33222
3 555
555
In the first case,
C题就是阶乘拆分问题,题目说的是,给你一个数字a,你把它的每一位分离出来,然后求阶乘,然后在乘起来,最后把这个结果分解为几个尽可能大的数字的组合,当然这个数字组起来也要大了,那么采取贪心的策略,尽可能的多把其他数字的阶乘分解掉2,3,5,7上面,依次枚举出来,比如说,2!=2!, 3!=3!,4!=3!*2!*2!,。。。
然后反过来输出就好了, 一开始关于反向输出的问题,卡了好久,但是最后还是想到了~
代码:
# include<cstdio> # include<iostream> using namespace std; int d[10]; char s[20]; int n; void meiju() { for ( int i = 0;i < n;i++ ) { if (s[i] == '0' || s[i] == '1') continue; else if (s[i] == '2') d[2]++; else if (s[i] == '3') d[3]++; else if (s[i] == '4') { d[3]++; d[2] += 2; } else if (s[i] == '5') d[5]++; else if (s[i] == '6') { d[5]++; d[3]++; } else if (s[i] == '7') d[7]++; else if (s[i] == '8') { d[7]++; d[2] += 3; } else { d[7]++; d[3] += 2; d[2] += 1; } } } int main(void) { cin>>n; cin>>s; meiju(); for ( int i = 9; i >= 0; i-- ) { while ( d[i]-- ) { cout<<i; } } cout<<endl; return 0; }
D题:
解题思路:这道题读完就想搜,因为先前做过很多的搜索题,都是这样的,但是这道题明确的是覆盖,也就是说用1*2的方砖去把这个网格中,所有空白的地方都覆盖住。
这题我当时也没出来,关键是时间不够用了,,,
可以先把每个空位置看做一个点,如果与这个点相邻的位置还有点的话,那么就可以放下一个1*2的砖块了。。。。这时候,就说这个空位置有一个度。
因为最终需要的是放砖的唯一解,并且要铺满整个n*m的格子,我们从度为1的点,开始一步一步的放。如果一开始遍历完成整个格子都没有发现度为1的格子,那么直接输出
Not unique.然后BFS,且度数为1的点放砖块只能有一种情况,那么边bfs,边放砖头,并且及时更新度数,如果出现了度数为1的格子就把它加到队列里面中去,
最后bfs下,再判断是否所以空位置都被砖头覆盖了。。。。
代码:
/* 把每个空位置看做一个点,如果与它相邻还有个空位置,也就是能放一个1×2的砖块,就叫做有一个度。 因为要找放砖块的唯一解,所以我们从度数为1的点开始放。如果没有的话,说明无解或多解,直接输出“Not unique” 然后BFS,度数为1的点放砖块只有一个方向,所以我们边BFS边放砖块,并及时更新度数,如果出现了新的度数为1的点就加到队列里面去。 BFS完后再判断一下是否所有的空位置都放上砖块了。 */ # include<cstdio> # include<iostream> # include<queue> # define PII pair<int,int> # define MP make_pair # define F first # define S second using namespace std; const int maxn = 2000 + 10; char s[maxn][maxn]; int deg[maxn][maxn]; int dx[] = {1, 0, -1, 0}; int dy[] = {0, 1, 0, -1}; char fillchar[2][5] = { "^<v>", "v>^<" }; inline int caldeg(int i, int j)//计算该点的度数 { return (int)(s[i-1][j] == '.') + (int)(s[i+1][j] == '.') + (int)(s[i][j-1] == '.') + (int)(s[i][j+1] == '.'); } int main(void) { int n, m; scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++i) scanf("%s", s[i]+1); queue<PII> Q; int cnt = 0;//统计空位置的个数 for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) if ( s[i][j] == '.' ) { deg[i][j] = caldeg(i, j); cnt++; if( deg[i][j] == 1 ) Q.push(MP(i, j)); } if( cnt & 1 ) { puts("Not unique"); return 0; } while(!Q.empty()) { PII cur = Q.front(); Q.pop(); int x = cur.F; int y = cur.S; if(s[x][y] == '.') { int i, nx, ny; for(i = 0; i < 4; ++i) { nx = x + dx[i]; ny = y + dy[i]; if(s[nx][ny] == '.') break; } if( i == 4 ) { puts("Not unique"); return 0; } s[x][y] = fillchar[0][i];//放砖块 s[nx][ny] = fillchar[1][i]; deg[x][y] = deg[nx][ny] = 0; cnt -= 2; for(i = 0; i < 4; ++i) { int nnx = nx + dx[i]; int nny = ny + dy[i]; if(s[nnx][nny] == '.') { deg[nnx][nny]--;//更新周围点的度数 if(deg[nnx][nny] == 1) Q.push(MP(nnx, nny)); } } } } if(cnt != 0) puts("Not unique");//还存在空位置 else for(int i = 1; i <= n; ++i) printf("%s\n", s[i]+1); return 0; }
E题: