哈尔滨华德学院-新生编程挑战赛

发布时间 2023-12-03 17:05:24作者: Ke_scholar

哈尔滨华德学院-新生编程挑战赛

A-签到_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

签到

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n;
	cin >> n;
	map<int,int> mp;
	for(int i = 0;i < n;i ++){
		int x;
		cin >> x;
		if(mp.count(x)) continue;
		cout << x << ' ';
		mp[x] ++;
	}

	return 0;
}

B-百分之x的信心_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	double n;
	cin >> n;
	double ans = round(n * 100.0);
	int x = ans;
	ans = x;
	cout << ans << '%';

	return 0;
}

C-幻方_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	i64 n;
	cin >> n;
	i64 x = (n * n + 1) / 2;
	cout << x * n << ' ' << x << '\n';

	return 0;
}

D-不是幻方_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

行和列逆着输入,就能用\(sort\)对每一列排序,输出也是行列交换输出

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	i64 n;
	cin >> n;
	vector g(n,vector<int>(n));
	for(int i = 0;i < n;i ++)
		for(int j = 0;j < n;j ++)
			cin >> g[j][i];

	for(auto &i : g){
		sort(i.begin(),i.end());
	}

	for(int i = 0;i < n;i ++)
		for(int j = 0;j < n;j ++)
			cout << g[j][i] << " \n"[j == n - 1];

	return 0;
}

E-要长脑子辣!!!_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

\[\begin{aligned} x &= \frac{\sum_{i=0}^n(a_i\cdot b_j)}{(\sum_{i=0}^na_i)^x+(\sum_{i=0}^n b_i)^y} \end{aligned} \]

数据范围是\(1\leq n,a_i,b_i\le 100,1\le x,y\le10\)

如果直接暴力的话可能会产生\(1e40\)的的大数字,而这在\(C++\)中甚至\(int128\)也不行,不知道python

假如用\(a\)表示\(\sum_{i=0}^na_i\),用\(b\)表示\(\sum_{i=0}^nb_i\),用\(c\)表示\(\sum_{i=0}^n(a_i\cdot b_i)\),则可以简化成:

\[\begin{aligned} x&=\frac{c}{a^x+b^y}\\ &=\frac{1}{\frac{a^x+b^y}{c}}\\ &=\frac{1}{\frac{a^x}{c}+\frac{b^y}{c}} \end{aligned} \]

这个时候\(a,b\)还是可能超出范围,那我们可以将\(a,b,c\)进行质因数分解,即:

\[\begin{aligned} a &= p_0^{a_1}\cdot p_1^{a_2}\cdot p_2^{a_3}\dots\\ b &= p_0^{b_1}\cdot p_1^{b_2}\cdot p_2^{b_3}\dots\\ c &= p_0^{c_1}\cdot p_1^{c_2}\cdot p_2^{c_3}\dots \end{aligned} \]

其中\(p_i\)表示质因子,\(a_i/b_i/c_i\)代表次方,然后就是用质因子的次方去进行一个约分,,最后把约分完的因子乘起来就是约分后的值了,假设\(\frac{a^x}{c}\)约分后为\(\frac{xa}{xc}\),\(\frac{b^y}{c}\)约分后为\(\frac{xb}{cc}\),

则有:

\[\begin{aligned} x&=\frac{1}{\frac{xa}{xc}+\frac{xb}{cc}}\\ &=\frac{xc\cdot cc}{xa\cdot cc + xb\cdot xc} \end{aligned} \]

这个时候分子分母都不会超过\(longlong\)范围,可以直接用\(gcd\)函数约分了.

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

long long ksm(long long a, long long b) {
	long long res = 1;
	while (b) {
		if (b & 1)res = res * a;
		b >>= 1;
		a = a * a;
	}
	return res;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	i64 n, x, y;
	cin >> n >> x >> y;
	i64 a = 0, b = 0, c = 0;
	vector<int> sa(n), sb(n);
	for (int i = 0, x; i < n; i ++) {
		cin >> x;
		sa[i] = x;
		a += x;
	}
	for (int i = 0, x; i < n; i ++) {
		cin >> x;
		sb[i] = x;
		b += x;
		c += sa[i] * sb[i];
	}

	vector<PII> A, B, C;
	for (int i = 2; i <= a / i; i ++) {
		if (a % i == 0) {
			i64 res = 0;
			while (a % i == 0)
				a /= i, res ++;
			A.emplace_back(i, res * x);
		}
	}
	if (a > 1) A.emplace_back(a, x);
	for (int i = 2; i <= b / i; i ++) {
		if (b % i == 0) {
			i64 res = 0;
			while (b % i == 0)
				b /= i, res ++;
			B.emplace_back(i, res * y);
		}
	}
	if (b > 1) B.emplace_back(b, y);

	for (int i = 2; i <= c / i; i ++) {
		if (c % i == 0) {
			i64 res = 0;
			while (c % i == 0)
				c /= i, res ++;
			C.emplace_back(i, res);
		}
	}
	if (c > 1) C.emplace_back(c, 1);

	i64 xa = 1, xc = 1;
	auto CC = C;
	int i = 0, j = 0;
	for (; i < A.size() && j < C.size();) {
		if (A[i].first == C[j].first) {
			i64 k = A[i].second;
			A[i].second = max(0ll, k - C[j].second);
			C[j].second = max(0ll, C[j].second - k);
			xa *= ksm(A[i].first, A[i].second), i ++;
			xc *= ksm(C[j].first, C[j].second), j ++;
		} else if (A[i].first < C[j].first) {
			xa *= ksm(A[i].first, A[i].second), i ++;
		} else
			xc *= ksm(C[j].first, C[j].second), j ++;
	}
	while (i < A.size()) {
		xa *= ksm(A[i].first, A[i].second), i ++;
	}
	while (j < C.size()) {
		xc *= ksm(C[j].first, C[j].second), j ++;
	}

	i64 xb = 1, cc = 1;
	for (i = 0, j = 0; i < B.size() && j < CC.size();) {
		if (B[i].first == CC[j].first) {
			i64 k = B[i].second;
			B[i].second = max(0ll, k - CC[j].second);
			CC[j].second = max(0ll, CC[j].second - k);
			xb *= ksm(B[i].first, B[i].second), i ++;
			cc *= ksm(CC[j].first, CC[j].second), j ++;
		} else if (A[i].first < C[j].first) {
			xb *= ksm(B[i].first, B[i].second), i ++;
		} else
			cc *= ksm(CC[j].first, CC[j].second), j ++;
	}
	while (i < B.size()) {
		xb *= ksm(B[i].first, B[i].second), i ++;
	}
	while (j < CC.size()) {
		cc *= ksm(CC[j].first, CC[j].second), j ++;
	}

	i64 fenzi = xc * cc, fenmu = xa * cc + xb * xc;
	i64 g = gcd(fenzi, fenmu);
	fenzi /= g, fenmu /= g;
	if (fenmu == 1)
		cout << fenzi << '\n';
	else
		cout << fenzi << '/' << fenmu << '\n';

	return 0;
}

F-Huadeyyds_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

数据小,直接暴力

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string s , tar = "Huade";
    cin >> s;
    i64 ans = 0;
    string res = "";
    for (int i = 0; i < s.size(); i ++) {
        if (s.substr(i, 5) == tar) {
            ans ++ ;
            res += "Huadeyyds";
            i += 4;
        } else
            res += s[i];
    }
    if (ans)
        cout << ans << '\n' << res << '\n';
    else
        cout << '0';

    return 0;
}

G题赛时放错题了来着

H-神奇"?"_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

暴力

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	string s,st;
	cin >> s >> st;
	int ans = 0;
	for(int i = 0;i < s.size();i ++){
		string res = s.substr(i,st.size());
		int l = 0, r = 0;
		while(l < res.size() && (res[l] == st[r] || res[l] == '?')){
			l ++, r ++;
		}
		if(l == st.size()) ans ++;
	}
	
	cout << ans << '\n';

	return 0;
}

I-Crazy 小飞象!_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

\(bfs\)

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, m, x, y;
	cin >> n  >> m >> x >> y;
	int u[] = {2,2,-2,-2} ,v[] = {2,-2,2,-2};
	vector g(n + 1,vector<int>(m + 1,-1));
	g[x][y] = 0;
	queue<PII> Q;
	Q.push({x,y});
	vector<bitset<410>> vis(410);
	vis[x][y] = 1;
	while(Q.size()){
		auto [dx,dy] = Q.front();
		Q.pop();

		for(int i = 0;i < 4;i ++){
			int xd = dx + u[i];
			int yd = dy + v[i];
			if(xd > 0 && xd <= n && yd > 0 && yd <= m && !vis[xd][yd]){
				g[xd][yd] = g[dx][dy] + 1;
				vis[xd][yd] = 1;
				Q.push({xd,yd});
			}
		}
	}

	for(int i = 1;i <= n;i ++)
		for(int j = 1;j <= m;j ++)
			cout << g[i][j] << " \n"[j == m];

	return 0;
}

J-幸存者_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

约瑟夫问题变种,就是把第\(k+1\)个循环输出即可

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, k;
	cin >> n >> k;
	queue<int> Q;
	for (int x, i = 1; i <= n; i ++) {
		cin >> x;
		Q.push(x);
	}

	Q.push(Q.front());
	Q.pop();
	int now = 1;
	while (Q.size() > 1) {
		if (now % (k + 1) == 0) {
			cout << Q.front() << ' ';
		} else
			Q.push(Q.front());
		now ++;
		Q.pop();
	}

	return 0;
}

K-喝“水题”_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;
using i64 = long long;

typedef pair<i64, i64> PII;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	double R, r, H, h;
	cin >> R >> r >> H >> h;
	double ans = 2.0 * 3.14 * R * R * R + 3.14  * (H * R * R - h * r * r);
	printf("%.2lf\n", ans / 3.0);

	return 0;
}

L-小成背单词_哈尔滨华德学院-新生编程挑战赛(同步赛) (nowcoder.com)

线段树板子题

#include <bits/stdc++.h>
#define debug(a) cout<<#a<<"="<<a<<'\n';

using namespace std;

#define MAXN 100010
#define INF 0x3fffffff

string A[MAXN];         //操作的序列,记得为(1...n)非(0...n)

struct node
{
    int left;
    int right;
    string max;           //维护最大值
} Tree[MAXN << 2];     //存储线段树

void maintain(int root)         //向上调整,使得让线段树维护区间最小值最大值区间和
{
    int LC = root << 1;     //此根的左孩子
    int RC = (root << 1) + 1;   //此根的右孩子
    Tree[root].max = max(Tree[LC].max, Tree[RC].max);       //根的最大值
}

void Build(int root, int start, int end)                   //构建线段树
{   //初始化时传入Build(1,1,n);
    Tree[root].left = start;            //建区间大小
    Tree[root].right = end;
    if (start == end)                   //当到达叶子节点时
    {
        Tree[root].max = A[start];
        return;
    }
    int mid = (start + end) >> 1;       //中间分开
    Build(root << 1, start, mid);       //对左孩子建树,左边孩子的编号为root*2
    Build((root << 1) + 1, mid + 1, end); //对右边孩子建树
    maintain(root);
}

void update(int root, int pos, string value)                   //更新点的值
{
    if (Tree[root].left == Tree[root].right && Tree[root].left == pos)  //更新叶子节点的值
    {
        Tree[root].max = value;
        return;
    }
    int mid = (Tree[root].left + Tree[root].right) >> 1;        //中间分开成两个区间
    if (pos <= mid)                                      //更新的值在左孩子
        update(root << 1, pos, value);                      //更新左孩子
    else
        update((root << 1) + 1, pos, value);            //更新的值在右孩子
    maintain(root);                                 //叶子节点更新完成后,会回溯到他的父节点,这样一直往上更新到根节点,维护线段树性质
}

string RmaxQ(int root, int start, int end)               //查询区间最大值
{
    if (start == Tree[root].left && Tree[root].right == end)
    {
        return Tree[root].max;
    }
    int mid = (Tree[root].left + Tree[root].right) >> 1;
    string ret = "114514";                                        //************可能是 (-INF)要尽可能的小
    if (end <= mid)
        ret = max(ret, RmaxQ(root << 1, start, end));   //完全左孩子区间匹配
    else if (start >= mid + 1)
        ret = max(ret, RmaxQ((root << 1) + 1, start, end)); //完全右孩子区间匹配
    else
    {
        string a = RmaxQ(root << 1, start, mid);
        string b = RmaxQ((root << 1) + 1, mid + 1, end);
        ret = max(a, b);                                //求的左右两个区间和匹配区间相符的最大值得较大者
    }
    return ret;                             //记得返回结果
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, q;
    cin >> n >> q;
    for (int i = 1; i <= n; i ++)
        cin >> A[i];
    Build(1, 1, 1e5 + 1);
    while (q--) {
        char op ;
        int x, y;
        string s;
        cin >> op ;
        if (op == 'Q') {
            cin >> x >> y;
            if (RmaxQ(1, x, y) == "114514") cout << "null\n";
            else cout << RmaxQ(1, x, y) << '\n';
        } else {
            cin >> x >> s;
            update(1, x, s);
        }
    }

    return 0;
}