【学校训练记录】11月个人训练赛4个人题解

A


题意可以理解为在a,b的范围内如果一个数是某个整数的立方,求与其距离为k的范围内有几个整数的平方数,我们可以对于每个立方数求出其数量,注意边界问题

#include <bits/stdc++.h>
#define int long long
using namespace std;

int a, b, k;
void solve(){
	cin >> a >> b >> k;
	int a1 = ceil(cbrt(a)), b1 = floor(cbrt(b));
	int sum = 0;
	for(int i = a1; i <= b1; i++){
		int x = i*i*i;
		int l = ceil(sqrt(max(x-k, a)));
		int r = floor(sqrt(min(x+k, b)));
		sum+=r-l+1;
	}
	cout << sum;
}
signed main (){
    solve();
    return 0;
}

B


观察不难看出,对于每一个次方数我们只需要
判断输出正负号,输出数字,输出x,以及^n
对于符号,只有在第一个数且为正时不输出
对于数字为1和-1时不输出,特殊的在最后一个需要输出
对于x只有最后一位1不输出
对于^n最后两位不输出

#include<bits/stdc++.h>
using namespace std;
int n,k[105],v;
int main(){
		cin>>n;
		for(int i=n;i>=0;i--)cin>>k[i];
		for(int i=n;i>=0;i--){
			if(k[i]!=0){
			if(i!=n&&k[i]>0) cout << "+";
			if(k[i]<0) cout << "-";
			if(abs(k[i])>1) cout << abs(k[i]);
			if(i>0) cout << "x";
			if(i>1) cout << "^" << i;
			if(i == 0 && abs(k[i]) == 1) cout << abs(k[i]);
		}
	}
		cout<<endl;
	return 0;
}

C


贪心,每次尽可能加入大的平方数

#include <bits/stdc++.h>
#define int long long
using namespace std;

int n; 
void solve(){
	cin >> n;
	int num = 0;
	while(n){
		
		n-=(int)sqrt(n)*(int)sqrt(n);
//		cout << n;
		num++;
	}
	cout << num;
}
signed main (){
    solve();
    return 0;
}

D


定义答案数组为b

a1 = b1/2+b2/2
a2 = b2/2+b3/2
...
an = bn/2+b1/2
化简得
b1 = 2a1-b2(1)
b2 = 2a1-b3(2)
...
bn = 2an-b1(n)
上面各式奇数项加,偶数项减得
b1 = 2a1-2a2+2a3-2a4..+2an-b1(n一定为奇数,故此处必为+2an-b1)
b1 = a1-a2+a3-a4+...+an
在将其带入之前的式子可得
b2 = 2a1-b1
b3 = 2a2-b2
bn = 2a(n-1)-b(n-1)

#include <bits/stdc++.h>
#define endl "\n"
#define int long long
using namespace std;

int n, a[100010], b[100010];
void solve(){
	cin >> n;
	memset(b,0,sizeof(b));
	for(int i = 1; i <= n; i++){
		cin >> a[i];
		if(i&1) b[1]+=a[i];
		else b[1]-=a[i];
	}	
	cout << b[1] << ' ';
	for(int i = 2; i <= n; i++){
		b[i] = 2*a[i-1]-b[i-1];
		cout << b[i];
		if(i!=n) cout << ' ';
	}
}
signed main (){
	ios::sync_with_stdio(false);
	cin.tie(nullptr); 
	int T;
//	cin >> T;
	T = 1;
	while (T--) {
		solve();
	}
	return 0;
}

F


对于#找出与其连接的.的数量,自身也算一个,预处理将每个区域的数量算出来,利用记忆化搜索记录数量,并将每一个区域作标记,因为同一区域只算一次

#include <bits/stdc++.h>
//#define int long long
using namespace std;

int n, m, a[1010][1010], b[1010][1010], d[1010][1010];
int num;
int ret;
char c[1010][1010];
int s1[4] = {0,0,1,-1};
int s2[4] = {1,-1,0,0};
void se(int x, int y){
	b[x][y] = num;
	d[x][y] = ret;
	for(int i = 0; i < 4; i++){
		int nx = x+s1[i];
		int ny = y+s2[i];
		if(nx>=1&&nx<=n&&ny>=1&&ny<=m){
			if(a[nx][ny]!=2 && c[nx][ny]=='.'){
				a[nx][ny]++;
				se(nx, ny);
			}
		}
	}
}
void dfs(int x, int y){
	num++;
	for(int i = 0; i < 4; i++){
		int nx = x+s1[i];
		int ny = y+s2[i];
		if(nx>=1&&nx<=n&&ny>=1&&ny<=m){
			if(a[nx][ny]!=1 && c[nx][ny]=='.'){
				a[nx][ny]++;
				dfs(nx, ny);
			}
		}
	}
}
void solve(){
	scanf("%d %d", &n, &m);
	getchar();
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			scanf("%c", &c[i][j]);
		}
		getchar();
	}
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			if(c[i][j]=='.' && a[i][j] == 0){
				a[i][j]++;
				dfs(i, j);
				ret++;
				se(i, j);
				num = 0;
			}
		}
	}
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			if(c[i][j] == '.') printf(".");
			else {
				int ret = b[i-1][j]+1;
				if(d[i+1][j]!=d[i-1][j]) ret+=b[i+1][j];
				if(d[i][j-1]!=d[i+1][j] && d[i][j-1]!=d[i-1][j]) ret+=b[i][j-1];
				if(d[i][j+1]!=d[i][j-1] && d[i][j+1]!=d[i+1][j] && d[i][j+1]!=d[i-1][j]) ret+=b[i][j+1];
				printf("%d", ret%10);
			}
		}
		printf("\n");
	}
}
signed main (){
    solve();
    return 0;
}
posted @ 2024-11-17 18:22  qkauto  阅读(47)  评论(0)    收藏  举报