计院
A 求众数
众数就是一个序列中出现次数最多的数字。 如果不唯一,则输出小的那个值。 给定第一个代表有几个数字。 1<=n<=10^5 每个数字在 int 范围内
样例:
输入, (第一个代表有几个数字)
8
10 3 8 8 3 2 2 2
输出 2
#include<iostream>
#include<cstring>
#include<map>using namespace std;
map<int,int> a;
int main(){int n;cin >> n;int d[n];for(int i = 0;i < n;i++) cin >> d[i];for(int i = 0;i < n;i++) {int x = d[i];if(a.find(x) != a.end()) a[x] += 1;else a.insert({x,1});}int max1 = 0,pos; //max1为出现最大次数,pos为出现最多的数字for(auto it = a.begin();it != a.end();it++) //map里按key值有序排列if(it -> second > max1){pos = it -> first;max1 = it -> second;}cout << pos;return 0;
}
学到的知识点
1.遍历map for(auto it = a.begin();it != a.end();it ++)
2.map查找函数,a.find(x),找到时返回该元素迭代器,找不到时返回a.end()。也可用a.count(x) == 0 来判断元素是否存在,
3.map中数据按照key值排序存储。
4.二元组可用{x,y}表示
或者可以先对数组排序(这样可以让相同数字连续出现),再依次统计每个数字出现次数,但不如map简单
B 解一元一次方程
#include<iostream>
#include<cstring>
using namespace std;char eq[256];bool isnox(char c){if(c == 'x') return false;return true;
}bool isnoop(char c){if(c == '+' || c == '-' || c == '=') return false; //=也是运算符return true;
}int main(){cin >> eq;int i = 0;int numl = 0,numr = 0,xl = 0,xr = 0;//处理左边while(eq[i] != '='){ char num_c[256];int k = 0;memset(num_c,NULL,sizeof num_c);bool flag = false; //用于x前无系数默认为1的情况int symbol = 1;if(eq[i] == '-') {symbol = -1;i++;}if(eq[i] == '+') i++;while( isnox(eq[i]) && isnoop(eq[i]) ){num_c[k++] = eq[i++];flag = true;}int num_i = 0;if(flag){for(int q = 0;q < k;q++){ //字符串变为数字intint ch = num_c[q] - '0';num_i = num_i * 10 + ch;}}else num_i = 1;if(eq[i] == 'x'){xl += num_i * symbol;i++;}else numl += num_i *symbol;}// cout << numl << ' ' << xl << ' ';i++;//处理右边while(eq[i] != NULL){ char num_c[256];int k = 0;memset(num_c,NULL,sizeof num_c);//*****bool flag = false; //用于x前无系数默认为1的情况int symbol = 1;if(eq[i] == '-') {symbol = -1;i++;}if(eq[i] == '+') i++;while( isnox(eq[i]) && isnoop(eq[i]) && eq[i]!= NULL ){num_c[k++] = eq[i++];flag = true;}int num_i = 0;if(flag){for(int q = 0;q < k;q++){ //字符串变为数字intint ch = num_c[q] - '0';num_i = num_i * 10 + ch;}}else num_i = 1;if(eq[i] == 'x'){xr += num_i * symbol;i++;}else numr += num_i *symbol;}
// cout << numr << ' ' << xr << ' ';int total_x = xl - xr,total_num = numr - numl;if(total_x == 0){if(total_num != 0) cout << "no solution";else cout << "infinite solutions";}else cout << "x=" << total_num / total_x;return 0;
}
写的有点长,就嗯模拟吧,比较繁琐的一道题。
C 骨牌
有2*n 的地板,用1*2和 2*1 的骨牌进行铺地板。问共有多少种情况。 结果对 999983 取余 。 1<=n<=10000 。 样例: 6 输出: 13
#include<iostream>
using namespace std;int dp[10000];int main(){int n;cin >> n;dp[1] = 1;dp[2] = 2;for(int i = 3;i <= n;i++)dp[i] = (dp[i -1]+ dp[i -2])%999983;cout << dp[n];
}
状态定义:dp[i]表示n为i时有多少种情况
状态划分:根据最后一块地板选1*2还是2*1划分、
经典DP,注意在求dp[i]时就要取余,否则会溢出int范围。
这种给一个数字求多少种情况的一般都是DP,可以找规律列状态转移方程。
工研院
A 集合交并
输入两个集合,分别求其交集和并集中元素的个数,每个集合中可能存在相同的元素,而最终的交集和并集中应该不存在。
输入描述:
第一行输入两个整数n,m表示两个集合中元素的个数 第二行输入n个整数,表示第一个集合中的元素 第三行输入m个整数,表示第二个集合中的元素
输出描述:
输出两个整数以空格分开,表示其交集和并集中元素的个数
输入样例#:
4 5 3 4 7 3 4 6 3 2 6
输出样例#:
2 5
#include<iostream>
#include<set>
using namespace std;int main(){int n,m;cin >> n >> m;set<int> a,b;for(int i = 0;i < n;i++) {int x;cin >> x;a.insert(x);}for(int i = 0;i < m;i++){int x;cin >> x;b.insert(x);}int num_j = 0,num_b = a.size() + b.size();for(auto x : a){if(b.find(x) != b.end()) num_j++;}num_b -= num_j;cout << num_j << ' ' << num_b;
}
B 约数求和
输入一个数n,输出前n个数的约数的和。
输入描述:
输入一个整数n,1<=n<=1e7
输出描述:
输出一个整数,前n个数的约数的和。
输入输出样例
输入样例:
7
输出样例:
41
#include <cstdio>int main(){int n; long long sum=0;scanf("%d", &n);for (int i=1; i<=n; i++){sum += i*(n/i);}printf("%lld\n", sum);
}