算法题-C++/python(6)

我变强了,但是仍然不够…

也许是笔试题变弱了也说不定

  1. 奖学金 AC

有挂科的某一门,即分数小于60,就不能获得奖学金,输出“No”

没有挂科,计算所有分数的均值与标准比较,大于等于标准分数,输出“Yes”,反之输出"No"

计算均值分:(sum(单科成绩*学分))/(学分总和)

输入:数据组数、一组数据里学科总数+标准分数、每个学科的学分、每个学科的分数

输出:“Yes”/“No”

#include
using namespace std;
int t;
const int N = 1005;
int n,avg;
int s[N];
int f[N];
int main()
{cin>>t;while(t--){scanf("%d%d",&n,&avg);int target = 0,SUM = 0;bool flag = false;for(int i=0;i<n;i++){scanf("%d",&s[i]);SUM+=s[i];}for(int i=0;i<n;i++){scanf("%d",&f[i]);if(f[i]>=60)target+=f[i]*s[i];else{flag = true;}}if(flag == false){if(target/SUM >= avg)cout<<"Yes"<<endl;elsecout<<"No"<<endl;}else{cout<<"No"<<endl;}}return 0;} 
  1. 小美投骰子 没暴力出来 0.27
    时间限制: 1000MS
    内存限制: 65536KB
    题目描述:
    小美需要制作一个骰子。与一般的六面骰子不同,小美需要的骰子总共有 n 面,而且每一面的数字也不同于一般的,这n面的数字需要分别是a1,a2,…an 。当然,骰子是一个正n面体,而且唯一合法的要求是所有相对的两面之和都需要相等,比如一个数字分别为 1,2,3,4,2,3 的六面骰子,那么上面1,下面4,前面2,后面3,左边2,右边3就是合法的方案。
    因为方案可以很多,所以小美并不在乎究竟是怎么做出这样一个骰子,小美只想知道是否能做出一个合法的骰子。当然,保证n为偶数。
    输入描述:
    第一行一个整数T,表示询问数据组数。
    对于每组询问:
    第一行一个正整数n,表示骰子的面数。
    接下来一行每行n个整数,分别为 a1,a2,…,an。
    设N=所有询问数据的n之和。
    对于所有的数据, 1≤T≤100, 1≤N≤105,1≤ai≤105,n为偶数。
    输出描述:
    对于每组询问,输出"YES"或者"NO"(不包含引号)表示能否拼成骰子。

    C++的垃圾暴力,直接用特殊条件判断

#include
using namespace std;
int t;
int n;
const int N=105;
int a[N];
long long SUM;
int main()
{cin>>t;while(t--){cin>>n;if(n%2==1){cout<<"NO"<<endl;continue;} else if(n==2){cout<<"YES"<<endl;continue;}for(int i=0;i<n;i++){scanf("%d",&a[i]);SUM+=a[i];}long long c = n/2;if(SUM % c==0) cout<<"YES"<<endl;else cout<<"NO"<<endl;// 任选两个数 和为固定值... }return 0;
}

写不出来直接用python莽一个

# 排序 加和==n+1
def solve(n, a):# 将数字按照从小到大的顺序排列a.sort()# 判断每组相对的数字之和是否相等for i in range(n//2):if a[i]+a[n-1-i] != a[0]+a[n-1]:return "NO"# 判断每个数字的相对数字是否符合要求cnt = [0] * (n+1)for i in range(n):j = n-1-icnt[a[i]] += 1cnt[a[j]] += 1if cnt[a[i]] != cnt[a[j]]:return "NO"return "YES"n = int(input())
a = list(map(int, input().split()))
print(solve(n, a))
  1. 种田 AC

    有N种作物,它们的购入价值是ai,卖出价值是bi,成熟消耗天数是ti。

    有一块地,可以种M天,问过M天之后,能够获得的最大价值是多少?

    嗯,完全背包板子题,直接写就行了,不分析了。

#include
using namespace std;
int n,m;
const int N = 1e6;
int a[N],b[N],t[N],c[N]; 
int f[N];
int main()
{cin>>n>>m;for(int i=0;i<n;i++)scanf("%d",&t[i]);for(int i=0;i<n;i++)scanf("%d",&a[i]);for(int i=0;i<n;i++){scanf("%d",&b[i]);	c[i] = b[i]-a[i];}// 完全背包? for(int i=0;i<n;i++){for(int j=t[i];j<=m;j++)f[j] = max(f[j],f[j-t[i]]+c[i]);}cout<<f[m]<<endl;return 0;
}
  1. 删除01串 0.27 刚刚开始做就觉得阴间 又是一题讨巧的
    时间限制: 1000MS
    内存限制: 65536KB
    题目描述:
    小美给你一个长度为 n 的01串(仅包含字符0和1的串),你可以删除这个串的一个前缀和一个后缀(可以为空),即保留一个原串的连续子串,操作之后整个串的代价为下面两部分之和:

    (1)被删除的字符1的个数;
    (2) 剩下的子串的字符0的个数
    你需要最小化操作的代价,并将其输出。
    输入描述:
    输入仅一行,一个长度为 n 的01字符串。
    对于所有数据,1≤n≤105
    输出描述:
    输出仅一行,一个整数,表示最小的操作代价。

    思路是把目标字符串拆分成三个部分:前缀、中间字串、后缀

    前缀统计1的个数,后缀统计1的个数 ->删除1有花费

    中间子串统计0的个数 ->保留0的花费

    s = input()
    def min_cost(s):n = len(s)ans = float('inf')zeros = s.count('0')ones = s.count('1')if zeros == 0 or ones == 0 or zeros == n:return 0# 只删除前缀或后缀的情况ans = min(ans, s.count('0'))# cost = 子串里有0个数for i in range(n):for j in range(n-1, i,-1):cost = s[:i].count('1') + s[j:n-1].count('1')if i < j:cost += s[i:j].count('0')ans = min(ans, cost)return ansprint(min_cost(s))
    
    // 用python写出来了 这里可以用c++改装一下
    #include
    using namespace std;
    // algorithm里面有count函数 可以统计string里的字符个数 
    int min_cost(string s) {int n = s.size();int ans = INT_MAX;int c0 = 0;for (char c : s) {if(c=='0') c0+=1;}if (c0 == 0 || c0 == n) {return 0;}ans = min(ans, c0); // 只删除前缀或后缀的情况for (int i = 0; i < n; i++) {for (int j = n-1; j >=0; j--) {int cost = count(s.begin(), s.begin()+i, '1') // 前缀的1个数 + count(s.begin()+j, s.end(), '1'); // 后缀的1个数 if (i < j) {cost += count(s.begin()+i, s.begin()+j, '0');// 中间串的0个数 }ans = min(ans, cost);}}return ans;
    }int main() {string s;cin >> s;cout << min_cost(s) << endl;return 0;
    }
    
  2. 小美打比赛 0.18
    时间限制: 1000MS
    内存限制: 65536KB
    题目描述:
    小美正在参加一个比赛。

    这个比赛总共有 2^k 个人参加(包括小美),编号为1,2,…,2^k,开始的时候所有人都在同一个小组。比试的规程如下:假设当前小组有 n 个人(n 为偶数),那么编号大小前 n/2 人分为一个新的小组,后 n/2 人分为一个新的小组,然后两个小组内部分别比试,决出各自的胜者,然后两个小组的胜者进行比试,胜者作为当前小组的优胜者,直到决出最初的小组的优胜者。当然一个人的小组优胜者肯定是他自己。

    例如如果当前小组有 4 个人,编号为1,2,3,4,那么就会将 1,2 分为一组,3,4分为一组分别比试,然后 1,2 中的胜者和 3,4 中的胜者再进行比试,决出整个小组的胜者。

    由于每个人的能力各不相同,小美预测了所有人两两比试时的胜者,现在小美想知道预测最终的胜者是谁。

    输入描述
    第一行一个正整数k ,表示总人数为2^k 。

    接下来2^k行,第 i 行2^k个整数 。

    其中v[i,j]=i 或 j 表示 i , j 进行比试的胜者。

    对于所有的数据,1≤k≤8, 1≤v[i,j]≤2^k

    输出描述
    输出一个整数表示最后的胜者的编号。

    思路没有,就是菜。

    后面问chatgpt写的,不过也是我自己改好的,它自己写的会出错。

    一个简单递归加二分就可以了。

    测试数据:

    2
    1 2 3 1
    2 2 3 2
    3 3 3 3
    1 2 3 4

    输出:3

    #include
    using namespace std;
    const int MAXN = 1 << 8;
    int k;
    int v[MAXN + 5][MAXN + 5];
    int c;
    // 比赛函数
    int compete(int l, int r) {if (l == r) return l;int m = (l + r) / 2;int w1 = compete(l, m);int w2 = compete(m + 1, r);
    //    cout<<"w1:"<
    //    cout<if(v[w1][w2]==w2) {return w2;}else{return w1;}
    }int main() {cin >> k;
    //    cout<<(1<*2 for (int i = 1; i <= 1<<k; i++) {for (int j = 1; j <= 1<<k; j++) {cin >> v[i][j];}}cout << compete(1, 1<<k) << endl;return 0;
    }
    


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部