打卡第一天
A. Little Artem
题意:给你n*m个方格,其中你可以涂上B或W,其中设如果B四周内有W这种B的个数为x,如果W四周内有B,这种W的个数为y,如果x=y+1,则成功,请你输出任意一种符合该条件的涂色方案。
思路:一开始想的是B和W交替出现,想了半天 直接一个顶角为W,其余都为B就行,这样x=2,y=1,直接出答案
#include <iostream>
using namespace std;
int main(){
ios::sync_with_stdio(0);
int t;
cin>>t;
while(t--){
int n, m;
cin>>n>>m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(i==1&&j==1) printf("W");
else printf("B");
}
printf("\n");
}
}
return 0;
}
B. Kind Anton
题意:多组输入t,之后输入一个n表示数组长度,然后输入数组a和b,但是a有一个限制条件,那就是a中的数组的值只能为0,1,-1,同时a能进行任意多次操作令a[j]=a[i]+a[j],(i<j),求是否存在操作使得数组a转变为数组b
思路:a数组中的数值很有意思,只能为0,-1,1,所以说对a[i]和b[i]进行分析可以得出一个结论
1.如果a[i]>b[i],如果对于a[i]来说,i之前不包括i,a[i]数组出现过-1,即能使得a[i]变小,即成立
2.如果a[i]<b[i],同理,如果在a[i]之前出现过1,则成立
3.如果a[i]=b[i],不须做处理
以上三个条件有一个不满足即不能使得a变为b
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <deque>
#include <cstring>
#include <algorithm>
using namespace std;
#define sc(x) scanf("%lf", &x)
const int mod = 1e9+7;
typedef long long ll;
const int M = 100010;
int a[M], b[M];
int main(){
ios::sync_with_stdio(0);
int t;
cin>>t;
while(t--){
int n;
cin>>n;
int flag[3]={0};
int tmp = 1;
for(int i = 0; i < n; i++) cin>>a[i];
for(int i = 0; i < n; i++){
cin>>b[i]; //其实如果为了节省空间可以不用另设b数组
if(a[i]>b[i]&&flag[2]);
else if(a[i]==b[i]);
else if(a[i]<b[i]&&flag[1]);
else tmp=0;
if(a[i]==1) flag[1] = 1;
else if(a[i]==-1) flag[2] = 1;
}
if(tmp) printf("YES\n");
else printf("NO\n");
}
return 0;
}
C. Eugene and an array
题意:输入n表示数组长度,之后n个数为数组a的值,对a进行的操作可以为在开头或者结尾去除掉0至n个数,称为子数组,对于这个子数组来说如果其子数组没有sum=0的话就算为好数组,输出数组a有多少个好数组
思路:对前i个数求和即sum,如果sum在前面出现过则表明这i个数中有一段[j+1,i]的sum=0(j<=i),简而言之就是sum(a[1]+…+a[j])=sum(a[1]+…+a[j-1]+a[j]+…+a[i]),sum[a[j+1]+…+a[i])=0,所以选取子数组只能在这j到i里面选即为i-j-1,但问题又来了,如果这i-j中有一段是sum=0的怎么办,这里引用一个变量tmp表示距离i最近的存在sum=0的,而且这个tmp的值对于每个i来说都有用处,即便是sum[i]在前面没有出现过也是一样的道理,具体实现看代码
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
#define sc(x) scanf("%lf", &x)
const int mod = 1e9+7;
typedef long long ll;
const int M = 200010;
int a[M];
int main(){
ios::sync_with_stdio(0);
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]); //存储数据
map<ll, ll> m;
m[0]=0; //注意这里的m[0]=0预处理对于和为0
ll ans = 0, sum = 0, tmp=0; //ans表示子数组的个数,sum表示前i个的和,
//tmp表示距离i最近的某个区间存在sum=0的下标
for(int i = 1; i <= n; i++){
sum += a[i];
if(m.count(sum)){ //如果sum在前面出现过
tmp = max(tmp, m[sum]+1); //max的意思就是如果这段j到i中存在sum=0的一小段取离i最近的
}
m[sum] = i; //对m进行更新
ans += i-tmp; //加i的意思是加上这个数字子数长度分别为1到i,由这个数往前推,
//减去tmp的意思是前面的i是有1到tmp这段是不能加入这个子数组的
}
printf("%lld\n", ans);
return 0;
}
D. Challenges in school №41
待补
F. Kate and imperfection
emmmm相对于F这题的确有点水
题意:给你一个整数n,然后从中选出K个数(这K个数是你可以决定的),之后在你选出的K个数中取其中任意两个数(注意这里是任意)求他们的gcd(a,b),即最大公因数,输出n-1个数,k的取值为2到n
思路:看到这个题目首先想到的是素数筛,因为素数之间的公因数是1,然后是逐步推,把素数筛选完之后,加入的数就肯定是合数,也可以得到一个结论加入合数后,他的次大因数必定在你选的k-1个数中。(最大因数为本身)
蒟蒻代码
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
#define sc(x) scanf("%lf", &x)
const int mod = 1e9+7;
typedef long long ll;
const int maxn = 500010;
int isp[maxn];
int n;
int p[maxn], len;
void init() {
isp[0] = isp[1] = 1;
for (int i = 2; i <= n; i++) {
if(!isp[i]) p[++len] = i;
for (int j = 1; j <= len && p[j]*i <= n; j++) {
isp[i*p[j]] = p[j]; //isp中存放的是i的最小因数,如果i为质书isp的值为0
if (i%p[j] == 0) break;
}
}
}
int a[maxn];
int main(){
ios::sync_with_stdio(0);
scanf("%d", &n);
init();
int j = 1;
for(int i = 2; i <= n; i++){
if(isp[i]!=0){
int tmp = max(i/isp[i], isp[i]);
a[tmp]++; //i的次大因数,i为合数
}else a[1]++;
}
for(int i = 2; i <= n; i++){
if(a[j]) printf("%d", j),a[j]--;
else j++, printf("%d", j), a[j]--;
if(i!=n) printf(" ");
}
return 0;
}
大佬代码
看到这代码量,我哭了
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int mod = 1e9+7;
typedef long long ll;
const int maxn = 500010;
int main(){
ios::sync_with_stdio(0);
int n;
cin>>n;
vector<int> ans(n+1,1);
for(int i = 2; i <= n; i++)
for(int j = i+i; j <= n; j+=i)
ans[j] = i;
sort(ans.begin(), ans.end());
for(int i = 2; i <= n; i++) cout<<ans[i]<<" ";
return 0;
}