天津大学智算2026预推免机试第二批题目及代码c++

发布于:2025-09-10 ⋅ 阅读:(23) ⋅ 点赞:(0)

平时刷题感觉还行,但是一到考试状态就不行。建议是平时多练,要追求做题速度和质量,因为真到了双机位、限时的考试场景,可能发挥只有平时的2/3。痛定思痛,晚上复盘了一把。


两个小时,五道题。类似蓝桥杯,需要自己写输入输出。代码在自己电脑的IDE写,然后复制粘贴到OJ平台上去测试,只会提示你样例是否通过,不会显示所有测试点的情况。我用的C++IDE是Dev C++。

犯的一些比较蠢的错误:=和==写错;变量命名为s1 s2结果写混了;


1.整数的权

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

int main()
{
	int n;
	cin>>n;
	while(n--){
		string s;
		cin>>s;
		long long ans=0;
		for(auto ss:s){
			long long a=(long long)(ss-'0');
			ans+=a*a;
		}
		cout<<ans<<endl;
	}
	
	return 0;
 } 

2.生日排序

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

bool cmp(vector<int> v1, vector<int> v2){
	if(v1[0]!=v2[0])return v1[0]<v2[0];
	else if(v1[1]!=v2[1]) return v1[1]<v2[1];
	else if(v1[2]!=v2[2]) return v1[2]<v2[2];
	else return v1[3]<v2[3];	
}

int main()
{
	int n;
	cin>>n;
	vector<vector<int>> v_num;
	vector<string> v_str;
	while(n--){
		string s;
		cin>>s;
		v_str.push_back(s);
		string sy,sm,sd;
		int y,m,d;
		int i=0,j=0;
		while(s[j]!='.')j++;
		sy=s.substr(i, j-i);
		i=++j;
		while(s[j]!='.')j++;
		sm=s.substr(i, j-i);
		i=j+1;
		sd=s.substr(i,s.size()-i);
		y=stoi(sy);
		m=stoi(sm);
		d=stoi(sd);
//		cout<<'!'<<y<<m<<d;
		vector<int> temp{y+m+d, y, m, d, v_num.size()};
		v_num.push_back(temp);
	}
	sort(v_num.begin(), v_num.end(), cmp);
	for(auto vv:v_num){
		cout<<v_str[vv[4]]<<endl;
//		cout<<'!'<<vv[0]<<vv[1]<<vv[2]<<vv[3]<<vv[4];
	}
	return 0;	
}

3.圆的位置

#include<bits/stdc++.h>
using namespace std;
using ll=long long;

int main(){
	int n;
	cin>>n;
	while(n--){
		ll x1,y1,r1,x2,y2,r2;
		cin>>x1>>y1>>r1>>x2>>y2>>r2;
		ll dist=(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
		ll sum_r=(r1+r2)*(r1+r2);
		ll min_r=(r1-r2)*(r1-r2);
		if(dist>sum_r){// 1. 相离:圆心距离 > 半径之和
			cout<<0<<endl;
		}
		else if(dist==sum_r || dist==min_r){// 2. 相切:圆心距离 = 半径之和 或 圆心距离 = |半径之差|
			cout<<1<<endl;
		}
		else if(dist<min_r){// 3. 包含:圆心距离 < |半径之差|
			cout<<3<<endl;
		}
		else{// 4. 相交
			cout<<2<<endl;
		}
	}
	return 0;
} 

4.节目安排

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

int main(){
	int p,t;
	cin>>p>>t;
	vector<int> times(p,0);
	for(int i=0;i<p;i++){
		cin>>times[i];
	}
	vector<int> dp(t+1, 0);
	for(auto time:times){
		for(int j=t;j>=time;j--){	
			dp[j]=max(dp[j], dp[j-time]+time);
		}
	}
	cout<<dp[t];
	return 0;
}

5.括号序列

下面的代码是ai写的,仍然有一些问题,仅供参考。

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

// 解决函数:将包含通配符的字符串转换为合法括号序列
string solve(string s) {
    int n = s.size();
    
    // dp[i][j]: 表示处理到前i个字符时,左括号比右括号多j个是否可能
    // 使用动态规划来跟踪所有可能的状态
    vector<vector<bool>> dp(n+1, vector<bool>(n+1, false));
    
    // path[i][j]: 表示在状态(i, j)下,能够形成的最小字典序字符串
    // 我们只记录最小字典序的路径,因为题目要求字典序最小
    vector<vector<string>> path(n+1, vector<string>(n+1, ""));
    
    // 初始化:处理0个字符时,左括号比右括号多0个是可能的,对应空字符串
    dp[0][0] = true;
    path[0][0] = "";
    
    // 动态规划处理每个字符
    for (int i = 0; i < n; i++) {
        for (int j = 0; j <= n; j++) {
            // 如果当前状态(i, j)不可达,跳过
            if (!dp[i][j]) continue;
            
            char current_char = s[i];  // 当前处理的字符
            
            // 选项1:将当前字符视为'('(当字符是'('或'*'时可选)
            // 因为'*'可以替换为'(',而'('本身就是左括号
            if (current_char == '(' || current_char == '*') {
                int new_balance = j + 1;  // 添加'('后,左括号比右括号多j+1个
                if (new_balance <= n) {   // 确保不会超出数组边界
                    string new_path = path[i][j] + "(";
                    // 如果新状态不可达,或者新路径字典序更小,则更新
                    if (!dp[i+1][new_balance] || new_path < path[i+1][new_balance]) {
                        dp[i+1][new_balance] = true;
                        path[i+1][new_balance] = new_path;
                    }
                }
            }
            
            // 选项2:将当前字符视为')'(当字符是')'或'*'时可选)
            // 注意:只有在当前左括号多于右括号(j > 0)时才能添加')'
            // 否则会出现非法序列(右括号多于左括号)
            if (current_char == ')' || current_char == '*') {
                if (j > 0) {  // 确保有足够的左括号来匹配这个右括号
                    int new_balance = j - 1;  // 添加')'后,左括号比右括号多j-1个
                    string new_path = path[i][j] + ")";
                    // 如果新状态不可达,或者新路径字典序更小,则更新
                    if (!dp[i+1][new_balance] || new_path < path[i+1][new_balance]) {
                        dp[i+1][new_balance] = true;
                        path[i+1][new_balance] = new_path;
                    }
                }
            }
            
            // 选项3:删除当前字符(只有当字符是'*'时才可选)
            // 因为只有'*'可以被删除,'('和')'必须保留
            if (current_char == '*') {
                string new_path = path[i][j];  // 保持原路径不变(相当于删除'*')
                // 如果新状态不可达,或者新路径字典序更小,则更新
                // 注意:删除操作保持平衡状态j不变
                if (!dp[i+1][j] || new_path < path[i+1][j]) {
                    dp[i+1][j] = true;
                    path[i+1][j] = new_path;
                }
            }
        }
    }
    
    // 检查最终状态:处理完所有字符后,左括号和右括号数量必须相等(j=0)
    // 并且该状态必须是可达的
    if (dp[n][0]) {
        return path[n][0];  // 返回最小字典序的合法括号序列
    } else {
        return "No solution!";  // 无法形成合法括号序列
    }
}

int main() {
    int T;
    cin >> T;  // 读取测试用例数量T
    
    // 处理每个测试用例
    while (T--) {
        string s;
        cin >> s;  // 读取包含通配符的字符串
        
        // 调用solve函数处理并输出结果
        cout << solve(s) << endl;
    }
    
    return 0;
}


网站公告

今日签到

点亮在社区的每一天
去签到