吉首大学第九届"新星杯"大学生程序设计大赛
A:
直接打表所有可以到达的点就可以了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 5e5 + 10; 20 const int MOD = 433494437; 21 22 template<class T>inline void read(T &res) 23 { 24 char c;T flag=1; 25 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 26 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 27 } 28 29 std::set<int> s1,s2; 30 int x,y,z; 31 32 int main() { 33 read(x);read(y);read(z); 34 s1.insert(0); 35 for (int i = 1;i <= 12;i++) { 36 for (auto it : s1) { 37 s2.insert(it + x); 38 s2.insert(it - x); 39 s2.insert(it + y); 40 s2.insert(it - y); 41 s2.insert(it + z); 42 s2.insert(it - z); 43 } 44 s1 = s2; 45 s2.clear(); 46 } 47 int q; 48 int now = 0; 49 read(q); 50 while (q--) { 51 int temp; 52 read(temp); 53 if (s1.count(temp-now)) { 54 printf("YES\n"); 55 now = abs(temp-now); 56 } 57 else { 58 printf("NO\n"); 59 now = 0; 60 } 61 } 62 return 0; 63 }
B:
分别统计行和列的磨损度然后取最大
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 1e5 + 10; 20 const int MOD = 433494437; 21 22 LL row[maxn],col[maxn]; 23 24 int main() { 25 int n,m; 26 while (~scanf("%d%d",&n,&m)) { 27 memset(row,0, sizeof(row)); 28 memset(col,0, sizeof(col)); 29 for (int i = 1;i <= n;i++) { 30 for (int j = 1;j <= m;j++) { 31 int key; 32 scanf("%d",&key); 33 row[i] += key; 34 col[j] += key; 35 } 36 } 37 LL ans = 0; 38 for (int i = 1;i <= n;i++) 39 ans = std::max(row[i],ans); 40 for (int i = 1;i <= m;i++) 41 ans = std::max(col[i],ans); 42 printf("%lld\n",ans); 43 } 44 return 0; 45 }
C:
审题注意一下只需要跑一次的BFS就可以了,然后就是很简单的方向BFS。最后进行一个结构体排序就好了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 5e5 + 10; 20 const int MOD = 433494437; 21 22 template<class T>inline void read(T &res) 23 { 24 char c;T flag=1; 25 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 26 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 27 } 28 29 int n,m,cnt; 30 int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}}; 31 int vis[105][105]; 32 char map[105][105]; 33 34 struct Node { 35 int x; 36 int y; 37 }node[maxn]; 38 39 bool cmp(Node a,Node b) { 40 if (a.x != b.x) 41 return a.x < b.x; 42 else 43 return a.y < b.y; 44 } 45 46 void dfs(int x,int y) { 47 for (int i = 0;i < 4;i++) { 48 int x1 = x + dir[i][0]; 49 int y1 = y + dir[i][1]; 50 if (!vis[x1][y1] && map[x1][y1] == '*' && x1 >= 1 && x1 <= n && y1 >= 1 && y1 <= m) { 51 vis[x1][y1] = 1; 52 continue; 53 } 54 if (vis[x1][y1] == 1 && map[x1][y1] == '*') { 55 vis[x1][y1] = 2; 56 node[cnt].x = x1; 57 node[cnt++].y = y1; 58 } 59 } 60 } 61 62 63 int main() { 64 while (~scanf("%d%d",&n,&m)) { 65 memset(vis,0, sizeof(vis)); 66 cnt = 0; 67 for (int i = 1;i <= n;i++) 68 scanf("%s",map[i]+1); 69 for (int i = 1;i <= n;i++) { 70 for (int j = 1;j <= m;j++) { 71 if (map[i][j] == '#') 72 dfs(i,j); 73 } 74 } 75 if (cnt == 0) { 76 printf("-1\n"); 77 continue; 78 } 79 std::sort(node,node+cnt,cmp); 80 for (int i = 0;i < cnt;i++) 81 printf("%d %d\n",node[i].x,node[i].y); 82 } 83 return 0; 84 }
D:
前几天刚做了一个和这个类似的题目。
对于求最小/大的符合条件的值的题目,我们都是采取二分答案的做法然后判断是否符合条件就可以了
这题就是典型的二分
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f 3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 2e6 + 10; 20 const int MOD = 433494437; 21 22 int n,m; 23 int a[maxn]; 24 25 bool check(int k) { 26 int time = 0; 27 for (int i = 1;i <= n;i++) { 28 if (a[i] % k == 0) 29 time += (a[i] / k); 30 else 31 time += (a[i] /k + 1); 32 if (time > m) 33 return false; 34 } 35 return time<=m; 36 } 37 38 39 int main() { 40 while (~scanf("%d%d",&n,&m)) { 41 int Max = 0; 42 for (int i = 1;i <= n;i++) { 43 scanf("%d", &a[i]); 44 Max = std::max(a[i],Max); 45 } 46 int l = 1,r = Max; 47 int ans = Max; 48 while (l <= r) { 49 int mid = (l + r) >> 1; 50 if (check(mid)) { 51 ans = mid; 52 r = mid - 1; 53 } 54 else 55 l = mid + 1; 56 } 57 printf("%d\n",ans); 58 } 59 return 0; 60 }
E:
sort就完事了
F:
这道题的规律其实很好找。 最后的答案就是 2^x * (每层容积) 求和
然后注意一下循环没有必要循环到真正的 1e15 (n的范围) ,因为阶层的增长的速度很快,我们打表发现 178!% mod 此时已经是0了,所以超过178的它的值就是0
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 5e5 + 10; 20 const LL MOD = 3777105087; 21 22 template<class T>inline void read(T &res) 23 { 24 char c;T flag=1; 25 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 26 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 27 } 28 29 LL a[maxn],d[maxn]; 30 31 void pre() { 32 a[0] = 1; 33 for (int i = 1;i < 11;i++) { 34 a[i] = 2 * a[i-1]; 35 } 36 } 37 38 void jie() { 39 d[1] = 1; 40 for (int i = 2;i <= 178;i++) { 41 d[i] = (i * d[i-1] ) % MOD; 42 } 43 } 44 45 int main() { 46 jie(); 47 pre(); 48 LL n; 49 while (~scanf("%lld",&n)) { 50 int x,y; 51 scanf("%d%d",&x,&y); 52 n = std::min(178ll,n); 53 LL sum = 0; 54 for (int i = 2;i <= n;i++) { 55 sum += d[i]; 56 sum %= MOD; 57 } 58 if (y) { 59 sum = (sum * a[x]) % MOD; 60 } 61 sum %= MOD; 62 printf("%lld\n",sum+1); 63 } 64 return 0; 65 }
G:
这场比赛G题是一个好题。
我们可以先进行下分类:1、长度超过m的肯定是符合条件的 2、长度等于m的部分符合条件
对于第一种情况:
我们可以用组合数的方式进行计算就好了(注意前导‘0’的情况)
对于第二种情况:
我们很容易想到采用dp的方式去优化
这里我们让 dp[i][j]代表 第一个字符串到 i 位置、第二个字符串取前 j 个的时候值相等的个数
转移方程:
因为我们统计的只是相等的情况,那么其实对于 ch1[i] > ch2[j] 或者 ch1[i] < ch2[j] 这两种情况我们直接把前面的转移过来就可以了 dp[i][j] = dp[i-1][j]
对于 ch1[i] = ch2[j] ,dp[i][j] = dp[i-1][j] + dp[i-1][j-1]
(不管此时的位置) (加上此时位置)
当 ch1[i] > ch2[j] 的时候我们可以利用组合数去计算 (dp[i-1][j-1] (前面相等的部分)在加上这大于的两个(ch1[i]、ch2[j] ) 后面的话就是自由组合了 )
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 5e5 + 10; 20 const LL MOD = 998244353; 21 22 template<class T>inline void read(T &res) 23 { 24 char c;T flag=1; 25 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 26 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 27 } 28 29 char p[maxn],s[maxn]; 30 31 32 LL C[3010][3010];//G++ long long 33 LL dp[3010][3010]; 34 void init() { 35 C[0][0] = 1; 36 for(int i = 1; i < 3010; i++) { 37 C[i][0] = 1; 38 for(int j = 1; j <= i; j++) { 39 C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % MOD; 40 } 41 } 42 } 43 int main() { 44 int t; 45 scanf("%d",&t); 46 init(); 47 while (t--) { 48 int n,m; 49 LL ans = 0; 50 scanf("%d%d",&n,&m); 51 scanf("%s",s+1); 52 scanf("%s",p+1); 53 for (int i = 1;i <= n && n - i >= m;i++) { 54 if (s[i] != '0') { 55 for (int k = m;k <= n-i;k++) { 56 ans = (ans + C[n-i][k] ) % MOD; 57 } 58 } 59 } 60 for (int i = 0;i <= n+1;i++) 61 dp[i][0] = 1; 62 for (int j = 1;j <= m;j++) { 63 for (int i = j;i <= n;i++) { 64 dp[i][j] = dp[i-1][j]; 65 if (s[i] == p[j]) 66 dp[i][j] = (dp[i-1][j] + dp[i-1][j-1]) % MOD; 67 else if (s[i] > p[j]) 68 ans = (ans + (dp[i-1][j-1] * C[n-i][m-j]) % MOD) % MOD; 69 } 70 } 71 printf("%lld\n",ans); 72 } 73 return 0; 74 }
H:
根据题意进行模拟就好了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f 3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 1e5 + 10; 20 const int MOD = 433494437; 21 22 int f[11]; 23 int ch[11][520][520] = {0}; 24 25 int main() { 26 int t; 27 f[1] = 1; 28 for (int i = 2;i <= 10;i++) 29 f[i] = 2 * f[i-1]; 30 ch[1][1][1] = 1; 31 for (int i = 2;i <= 10;i++) { 32 for (int j = 1;j <= f[i-1];j++) { 33 for (int k = 1,l = 1;k <= f[i];k++,l++) { 34 if (l > f[i-1]) 35 l = 1; 36 ch[i][j][k] = ch[i-1][j][l]; 37 } 38 } 39 for (int j = f[i-1]+1,row = 1;j <= f[i];j++,row++) { 40 for (int k = 1;k <= f[i-1];k++) { 41 ch[i][j][k] = !ch[i-1][row][k]; 42 } 43 for (int k = f[i-1]+1,l = 1;k <= f[i];k++,l++) 44 ch[i][j][k] = ch[i-1][row][l]; 45 } 46 } 47 scanf("%d",&t); 48 while (t--) { 49 int n; 50 scanf("%d",&n); 51 for (int i = 1;i <= f[n];i++) { 52 for (int j = 1;j <= f[n];j++) { 53 printf("%d ",ch[n][i][j]); 54 } 55 printf("\n"); 56 } 57 } 58 }
I:
利用二进制进行统计
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 1e5 + 10; 20 const int MOD = 433494437; 21 22 int Func(LL val) { 23 LL m = 1; 24 int cnt = 0; 25 for (int i = 1;i < 51;i++) { 26 if ((m & val) == m) { 27 cnt++; 28 } 29 m = m << 1; 30 } 31 return cnt; 32 } 33 34 int main() { 35 LL k; 36 while (~scanf("%lld",&k)) { 37 printf("%d\n",Func(k)); 38 } 39 return 0; 40 }
J:
题目的意思其实就是让你找最长的连续的个数
1 5 6 2 4 3
我们答案应该是 3
因为我们相当于找到最长连续的,这里是 1 2 3
转移方程 :dp[a[i]] = dp[a[i]-1] + 1
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 5e5 + 10; 20 const int MOD = 433494437; 21 22 template<class T>inline void read(T &res) 23 { 24 char c;T flag=1; 25 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 26 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 27 } 28 int a[maxn],dp[maxn]; 29 30 int main() { 31 int t; 32 read(t); 33 while (t--) { 34 int n; 35 read(n); 36 int Max = 0; 37 for (int i = 1;i <= n;i++) { 38 read(a[i]); 39 dp[i] = 0; 40 } 41 for (int i = 1;i <= n;i++) { 42 dp[a[i]] = dp[a[i]-1] + 1; 43 Max = std::max(Max,dp[a[i]]); 44 } 45 printf("%d\n",n-Max); 46 } 47 return 0; 48 }
K:
冰查鸡
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 5e5 + 10; 20 const LL MOD = 3777105087; 21 22 template<class T>inline void read(T &res) 23 { 24 char c;T flag=1; 25 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 26 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 27 } 28 29 int pre[1010],vis[1005]; 30 int tong[1005][15]; 31 char ch[1010]; 32 33 int find(int x) { 34 if (pre[x] == x) 35 return x; 36 return pre[x] = find(pre[x]); 37 } 38 39 void merge(int x,int y) { 40 int rootx = find(x),rooty = find(y); 41 pre[rooty] = rootx; 42 } 43 44 int main() { 45 int t; 46 scanf("%d",&t); 47 while (t--) { 48 memset(tong, 0, sizeof(tong)); 49 memset(vis,0, sizeof(vis)); 50 memset(pre,0, sizeof(pre)); 51 int n; 52 scanf("%d", &n); 53 for (int i = 1;i <= n;i++) 54 pre[i] = i; 55 for (int i = 1; i <= n; i++) { 56 memset(ch, '\0', sizeof(ch)); 57 scanf("%s", ch); 58 for (int j = 0; j < strlen(ch); j++) 59 tong[i][ch[j] - '0'] = 1; 60 } 61 for (int i = 1; i <= n; i++) 62 for (int j = i + 1; j <= n; j++) 63 for (int l1 = 0; l1 <= 9; l1++) 64 if (tong[i][l1] == tong[j][l1] && tong[i][l1]) 65 merge(i, j); 66 int cnt = 0; 67 for (int i = 1;i <= n;i++) 68 vis[find(i)] = 1; 69 for (int i = 1;i <= n;i++) 70 if (vis[i]) 71 cnt++; 72 printf("%d\n",cnt); 73 } 74 return 0; 75 }
L:
大模拟
不符合规则的几种情况优先判断。
我们先放一个,然后进行判断是否胜利。然后再放对手的一个,判断对手是否胜利。最后自己再放一个,判断自己是否胜利。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 5e5 + 10; 20 const LL MOD = 3777105087; 21 22 template<class T>inline void read(T &res) 23 { 24 char c;T flag=1; 25 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 26 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 27 } 28 29 char map[5][5]; 30 31 bool judge(char k) { 32 for (int i = 1;i <= 3;i++) 33 if (map[i][1] == k && map[i][2] == k && map[i][3] == k) 34 return true; 35 for (int i = 1;i <= 3;i++) 36 if (map[1][i] == k && map[2][i] == k && map[3][i] == k) 37 return true; 38 if (map[1][1] == k && map[2][2] == k && map[3][3] == k) 39 return true; 40 if (map[3][1] == k && map[2][2] == k && map[1][3] == k) 41 return true; 42 return false; 43 } 44 45 bool win_1(char k) { 46 for (int i = 1;i <= 3;i++) { 47 for (int j = 1;j <= 3;j++) { 48 if (map[i][j] == '.') { 49 map[i][j] = k; 50 if (judge(k)) { 51 map[i][j] = '.'; 52 return true; 53 } 54 map[i][j] = '.'; 55 } 56 } 57 } 58 return false; 59 } 60 61 bool win_2(char k) { 62 if (judge(k)) 63 return true; 64 if (win_1(k == 'o' ? 'x' : 'o')) 65 return false; 66 for (int i = 1;i <= 3;i++) { 67 for (int j = 1;j <= 3;j++) { 68 if (map[i][j] == '.') { 69 if (k == 'o') 70 map[i][j] = 'x'; 71 else 72 map[i][j] = 'o'; 73 if (win_1(k)) 74 map[i][j] = '.'; 75 else { 76 map[i][j] = '.'; 77 return false; 78 } 79 } 80 } 81 } 82 return true; 83 84 } 85 86 bool solve(char k) { 87 for (int i = 1;i <= 3;i++) { 88 for (int j = 1;j <= 3;j++) { 89 if (map[i][j] == '.') { 90 map[i][j] = k; 91 if (win_2(k)) 92 return true; 93 map[i][j] = '.'; 94 } 95 } 96 } 97 return false; 98 } 99 100 int main() { 101 int t; 102 std::cin >> t; 103 while (t--) { 104 int cnto = 0,cntx = 0; 105 for (int i = 1;i <= 3;i++) { 106 for (int j = 1;j <= 3;j++) { 107 std::cin >> map[i][j]; 108 if (map[i][j] == 'o') 109 cnto++; 110 if (map[i][j] == 'x') 111 cntx++; 112 } 113 } 114 char temp; 115 std::cin >> temp; 116 if (temp == 'o') { 117 if (cnto > cntx) { 118 printf("wrong!\n"); 119 continue; 120 } 121 } 122 if (temp == 'x') { 123 if (cntx > cnto) { 124 printf("wrong!\n"); 125 continue; 126 } 127 } 128 if (abs(cnto - cntx) >= 2 || judge('o') || judge('x')) { 129 printf("wrong!\n"); 130 continue; 131 } 132 if (win_1(temp)) { 133 printf("LeeLdler win!\n"); 134 continue; 135 } 136 if (solve(temp)) { 137 printf("LeeLdler win!\n"); 138 continue; 139 } 140 else 141 printf("Cannot win!\n"); 142 } 143 return 0; 144 }
M:
从容积为0开始倒着往前推。
能直接到达0的肯定是先手必胜
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <math.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <iostream> 5 #include <algorithm> 6 #include <string> 7 #include <string.h> 8 #include <vector> 9 #include <map> 10 #include <stack> 11 #include <set> 12 #include <queue> 13 14 #define LL long long 15 #define INF 0x3f3f3f3f 16 #define ls nod<<1 17 #define rs (nod<<1)+1 18 19 const int maxn = 5e5 + 10; 20 const LL MOD = 3777105087; 21 22 template<class T>inline void read(T &res) 23 { 24 char c;T flag=1; 25 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 26 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 27 } 28 29 int a[maxn],d[maxn]; 30 31 int main() { 32 int n,m; 33 read(n);read(m); 34 for (int i = 1;i <= m;i++) 35 read(a[i]); 36 for (int i = 0;i <= n;i++) { 37 for (int j = 1;j <= m;j++) { 38 if (i + a[j] > n) 39 continue; 40 if (d[i] == 0) 41 d[i+a[j]] = 1; 42 } 43 } 44 if (d[n]) 45 printf("Y\n"); 46 else 47 printf("N\n"); 48 return 0; 49 }