题记:若立志投身算法研究,可精研理论算法:动态规划、递归、深度搜索等;若以解决问题为目的,主要为了工作内容,当尝试快而简单的方法,这该是学习的本意。
1.素数伴侣
素数又叫质数(prime number),有无限个。质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。
方案一:匈牙利算法
偶数+偶数=偶数,必不是素数,因此素数只能是奇数+偶数。我们把输入的这一组数分成奇数和偶数,就得到了二分图,在这两组之间用匈牙利算法作匹配。
1.首先我们遍历一遍所有数字,建立他们之间所有可能的联系,便于后面的调整。接下来开始找最优连接方案。
2.每次取奇数p,遍历偶数,判断是否能和奇数组成素数伴侣,如果偶数q没有和别人结成伴侣则建立p和q之间的关系;如果这个偶数q已经和别的奇数k结成伴侣,那么递归查找k的下一位能建立关系的偶数,如果找到了p和q建立关系,如果没有找到,则不改变偶数q和奇数k的关系。
#include <iostream>
#include<vector>
using namespace std;
bool isprime(int i)
{
for(int j=2;j*j<=i;j++)
{
if(i%j==0)
return false;
}
return true;
}
bool find(const int & n,vector<vector<bool>> &map,vector<int>& match,vector<bool>&visit)
{
for (int i = 0; i < match.size(); i++)
{
if (!visit[i] && map[i][n])
{
visit[i] = true;
if (match[i] == -1 || find(match[i], map, match, visit))
{
match[i] = n;
return true;
}
}
}
return false;
}
int main()
{
int n=0;
while(cin>>n)
{
int k=0;
vector<int> even;
vector<int> odd;
int count=0;
while(n--){
cin>>k;
if(k%2==0){
odd.push_back(k);
}else{
even.push_back(k);
}
}
if(odd.empty()||even.empty()){
cout<<count<<endl;
continue;
}
vector<vector<bool>> map(even.size(),vector<bool>(odd.size(),false));
for(int i=0;i<even.size();i++)
{
for(int j=0;j<odd.size();j++){
if(isprime(even[i]+odd[j])){
map[i][j]=true;
}
}
}
vector<int> match(even.size(),-1);
for (int i = 0; i < odd.size(); i++){
vector<bool> visit(even.size(), false);
if (find(i, map, match, visit))
{
count++;
}
}
cout << count << endl;
}
return 0;
}
方法二:
也是匈牙利算法,区别在于方法二去掉了了存储偶数和奇数之间关系的图,减少了空间,但是提高了时间复杂度,每次find函数递归遍历的时候都需要重新判断当前两个数是否为素数伴侣。
#include <iostream>
#include<vector>
using namespace std;
bool isprime(int i)
{
for(int j=2;j*j<=i;j++)
{
if(i%j==0)
return false;
}
return true;
}
bool find(const int & n,vector<int> &even,vector<int>& match,vector<bool>&visit)
{
for (int i = 0; i < even.size(); i++)
{
if (!visit[i] && isprime(even[i]+n))
{
visit[i] = true;
if (match[i] == -1 || find(match[i], even, match, visit))
{
match[i] = n;
return true;
}
}
}
return false;
}
int main()
{
int n=0;
while(cin>>n)
{
int k=0;
vector<int> even;
vector<int> odd;
int count=0;
while(n--){
cin>>k;
if(k%2==0){
odd.push_back(k);
}else{
even.push_back(k);
}
}
if(odd.empty()||even.empty()){
cout<<count<<endl;
continue;
}
vector<int> match(even.size(),-1);
for (int i = 0; i < odd.size(); i++){
vector<bool> visit(even.size(), false);
if (find(odd[i], even, match, visit))
{
count++;
}
}
cout << count << endl;
}
return 0;
}
2.Sudoku
从左上角开始去遍历这个数独。
对于没有填入的格子(即格子数值为0),我们去枚举1~9每个数字填入,然后根据数独的性质(同行、同列、同一个九宫格不能有相同数字)去判断填入。如果可以成功填完所有格子那么就是找到了答案。找到答案后可以用一个bool变量,然后注意在回溯的地方根据这个变量及时的return,防止已经找到答案后又回溯为0。
对于初始化就有值的格子,我们往右走(列数值加一),那么因为一行只有9个,所以当列走到头的时候,列的值变成0,行的值加1(其实就是换到了下一行的开头)。
#include <bits/stdc++.h>
using namespace std;
const int N = 15;
int mp[N][N];
bool find_answer_ok;
bool check(int row, int col, int val) {
for(int i = 0; i < 9; i++) {
if(mp[row][i] == val) {
return false;
}
}
for(int i = 0; i < 9; i++) {
if(mp[i][col] == val) {
return false;
}
}
int limit_row = row / 3 * 3 + 3;
int limit_col = col / 3 * 3 + 3;
for(int i = limit_row - 3; i < limit_row; i++) {
for(int j = limit_col - 3; j < limit_col; j++) {
if(mp[i][j] == val) {
return false;
}
}
}
return true;
}
void dfs(int row, int col) {
if(col == 9) {
row++;
col = 0;
}
if(row == 9 && col == 0) {
find_answer_ok = true;
return ;
}
if(mp[row][col] == 0) {
for(int i = 1; i <= 9; i++) {
if(check(row, col, i)) {
mp[row][col] = i;
dfs(row, col + 1);
if(find_answer_ok) {
return ;
}
mp[row][col] = 0;
}
}
} else {
dfs(row, col + 1);
}
}
int main() {
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
cin >> mp[i][j];
}
}
dfs(0, 0);
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
cout << mp[i][j] << ' ';
}
cout << endl;
}
return 0;
}
3.自动售货系统
困难
通过率:27.94%
时间限制:1秒
空间限制:32M
知识点
字符串
模拟
校招时部分企业笔试将禁止编程题跳出页面,为提前适应,练习时请使用在线自测,而非本地IDE。
描述
1 总体说明
考生需要模拟实现一个简单的自动售货系统,实现投币、购买商品、退币、查询库存商品及存钱盒信息的功能。
系统初始化时自动售货机中商品为6种商品,商品的单价参见1.1规格说明,存钱盒内放置1元、2元、5元、10元钱币,商品数量和钱币张数通过初始化命令设置,参见2.1 系统初始化。
1.1规格说明
1. 商品:每种商品包含商品名称、单价、数量三种属性,其中商品名不重复。考生不能修改商品名称和单价,初始化命令设置商品数量。这些信息在考试框架中进行定义,考生在实现功能代码时可直接使用。
商品
名称
|
单价
|
数量
|
A1 | 2 | X |
A2 | 3 | X |
A3 | 4 | X |
A4 | 5 | X |
A5 | 8 | X |
A6 | 6 | X |
2. 存钱盒信息:钱币面额、张数两种属性。初始化命令设置各种面额钱币张数。这些信息在考试框架中进行定义,考生在实现功能代码时可直接使用。
钱币面额
|
张数
|
10元
| X |
5元
| X |
2元 | X |
1元 | X |
3.
退币原则 :
1)
根据系统存钱盒内钱币的
信息
,按钱币总张数最少的原则进行退币。
2)
如果因零钱不足导致不能退币,则尽最大可能退币,以减少用户损失。
例如:假设存钱盒内只有4张2元,无其它面额钱币。如果需要退币7元,系统因零钱不足无法退币,则继续尝试退币6元,最终系统成功退币3张2元,用户损失1元钱币。
4. 投币操作说明:每次投币成功,投入的钱币面额累加到投币余额;同时,本次投入的钱币放入存钱盒中,存钱盒相应面额钱币增加。
5. 投币余额:指当前自动售货机中用户剩余的可购买商品的钱币总额;例如:投入2元面额的钱币,投币余额增加2元;购买一件价格2元的商品,投币余额减少2元;
6. 退币操作说明:退币操作需要遵守
退币原则 ;退币成功后,投币余额清零,同时扣除存钱盒相应的金额。
7. 购买商品操作说明:一次仅允许购买一件商品;购买商品成功后,自动售货机中对应商品数量减1,投币余额扣除本次购买商品的价格。
2 操作说明
命令字与第一个参数间使用一个空格分隔,多条命令采用分号隔开。考试系统会对输入命令格式进行处理,考生不需要关注输入
命令格式的合法性,只需要实现命令处理函数。
2.1 系统初始化
命令格式:
r A1
数量
-A2
数量
-A3
数量
-A4
数量
-A5
数量
-A6
数量
1
元张数
-2
元张数
-5
元张数
-10
元张数
参数名称
|
参数说明
|
类型
|
取值范围
|
A1数量
|
商品A1数量
|
整数
|
[0,30]
|
A2数量
|
商品A2数量
|
整数
|
[0,30]
|
A3数量
|
商品A3数量
|
整数
|
[0,30]
|
A4数量
|
商品A4数量
|
整数
|
[0,30]
|
A5数量
|
商品A5数量
|
整数
|
[0,30]
|
A6数量
|
商品A6数量
|
整数
|
[0,30]
|
1元张数
|
面额1元钱币张数
|
整数
|
[0,30]
|
2元张数
|
面额2元钱币张数
|
整数
|
[0,30]
|
5元张数
|
面额5元钱币张数
|
整数
|
[0,30]
|
10元张数
|
面额10元钱币张数
|
整数
|
[0,30]
|
商品和各种面额钱币取值范围只是作为初始化命令的限制,其它场景下不限制取值范围;考试框架已经实现取值范围的检查,考生不需要关注。
功能说明:设置自动售货机中商品数量和存钱盒各种面额的钱币张数;
约束说明:系统在任意阶段均可执行
r初始化系统;考生不需要关注参数的合法性,不需要关注增加或缺少参数的场景;
输出说明:输出操作成功提示(执行完
r命令后系统会自动输出操作结果,考生不需要再次调用输出函数),例:
命令 | 输出 | 含义 |
r 6-5-4-3-2-1 4-3-2-1; | S001:Initialization is successful | 初始化成功 |
2.2 投币
命令格式:
p
钱币面额
功能说明:
(1) 如果投入非1元、2元、5元、10元的钱币面额(钱币面额不考虑负数、字符等非正整数的情况),输出“E002:Denomination error”;
(2) 如果存钱盒中1元和2元面额钱币总额小于本次投入的钱币面额,输出“E003:Change is not enough, pay fail”,但投入1元和2元面额钱币不受此限制。
(3) 如果自动售货机中商品全部销售完毕,投币失败。输出“E005:All the goods sold out”;
(4) 如果投币成功,输出“S002:Pay success,balance=X”;
约束说明:
(1) 系统在任意阶段都可以投币;
(2) 一次投币只能投一张钱币;
(3) 同等条件下,错误码的优先级:E002 > E003 > E005;
输出说明:如果投币成功,输出“S002:Pay success,balance=X”。
例:
命令
|
输出
|
p 10;
|
S002:Pay success,balance=10
|
2.3 购买商品
命令格式:
b
商品名称
功能说明:
(1) 如果购买的商品不在商品列表中,输出“E006:Goods does not exist”;
(2) 如果所购买的商品的数量为0,输出“E007:The goods sold out”;
(3) 如果投币余额小于待购买商品价格,输出“E008:Lack of balance”;
(4) 如果购买成功,输出“S003:Buy success,balance=X”;
约束说明:
(1) 一次购买操作仅能购买一件商品,可以多次购买;
(2) 同等条件下,错误码的优先级:E006 > E007 > E008;
输出说明:
如果购买成功,输出“S003:Buy success,balance=X”。
例:
命令
|
输出
|
b A1;
|
S003:Buy success,balance=8
|
2.4 退币
命令格式:
c
功能说明:
(1) 如果投币余额等于0的情况下,输出“E009:Work failure”;
(2) 如果投币余额大于0的情况下,按照
退币原则 进行“找零”,输出退币信息;
约束说明:
(1) 系统在任意阶段都可以退币;
(2) 退币方式必须按照
退币原则 进行退币;
输出说明:如果退币成功,按照
退币原则 输出退币信息。
例,退5元钱币:
命令
|
输出
|
c;
|
1 yuan coin number=0
2 yuan coin number=0
5 yuan coin number=1
10 yuan coin number=0
|
2.5 查询
命令格式:
q
查询类别
功能说明:
(1) 查询自动售货机中商品信息,包含商品名称、单价、数量。
根据商品数量从大到小进行排序;商品数量相同时,按照商品名称的先后顺序进行排序 。
例如:A1的商品名称先于A2的商品名称,A2的商品名称先于A3的商品名称。
(2) 查询存钱盒信息,包含各种面额钱币的张数;
(3) 查询类别如下表所示:
查询类别
|
查询内容
|
|
查询商品信息
|
1 | 查询存钱盒信息 |
如果“查询类别”参数错误,输出“E010:Parameter error”。“查询类别”参数错误时,不进行下面的处理;
输出说明:
“查询类别”为0时,输出自动售货机中所有商品信息(商品名称单价数量)例:
命令
|
输出
|
q 0;
|
A1 2 6
A2 3 5
A3 4 4
A4 5 3
A5 8 2
A6 6 0
|
“查询类别”为1时,输出存钱盒信息(各种面额钱币的张数),格式固定。例:
命令
|
输出
|
q 1;
|
1 yuan coin number=4
2 yuan coin number=3
5 yuan coin number=2
10 yuan coin number=1
|
输入描述:
输出描述:
示例1
输入:
r 22-18-21-21-7-20 3-23-10-6;c;q0;p 1;b A6;c;b A5;b A1;c;q1;p 5;
复制
输出:
S001:Initialization is successful
E009:Work failure
E010:Parameter error
S002:Pay success,balance=1
E008:Lack of balance
1 yuan coin number=1
2 yuan coin number=0
5 yuan coin number=0
10 yuan coin number=0
E008:Lack of balance
E008:Lack of balance
E009:Work failure
E010:Parameter error
S002:Pay success,balance=5
算法实现
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<sstream>
using namespace std;
bool cmp(pair<pair<string, int>, int>& a, pair<pair<string, int>, int>& b){
if(a.second != a.second)
return a.second > b.second;
else
return a.first.first < b.first.first;
}
class Vending{
private:
vector<int> price = {2, 3, 4, 5, 8, 6};
int money = 0;
vector<int> goods;
vector<int> coins;
public:
void init(string& s){
money = 0;
s = s.substr(2, s.length() - 2);
goods.resize(6);
coins.resize(4);
goods[0] = goods[1] = goods[2] = goods[3] = goods[4] = goods[5] = 0;
coins[0] = coins[1] = coins[2] = coins[3] = 0;
int i = 0;
bool flag = false;
for(auto c: s){
if(isdigit(c) && !flag)
goods[i] = goods[i] * 10 + (c -' 0');
else if(isdigit(c) && flag)
coins[i] = coins[i] * 10 + (c - '0');
else if(c == ' '){
flag = true;
i = 0;
}
else if(c == '-')
i++;
}
cout << "S001:Initialization is successful" << endl;
}
void pay(string& s){
int num = 0;
for(auto &c: s)
if(isdigit(c))
num = num * 10 + (c - '0');
if(num == 1 || num == 2 || num == 5 || num == 10){
if(num > 2 && num > (coins[0] + coins[1] * 2))
cout << "E003:Change is not enough, pay fail" << endl;
else if((goods[0] || goods[1] || goods[2] || goods[3] || goods[4] || goods[5]) == 0)
cout << "E005:All the goods sold out" << endl;
else{
if(num == 1 || num == 2)
coins[num-1]++;
else if(num == 5)
coins[2]++;
else coins[3]++;
money += num;
cout << "S002:Pay success,balance=" << money << endl;
}
}
else
cout << "E002:Denomination error" << endl;
}
void buy(string& s){
if(s.length() == 4 && (s[2] == 'A') && (s[3] - '0' < 7) && isdigit(s[3]) && (s[3] != '0')){
if(goods[s[3] - '1'] == 0)
cout << "E007:The goods sold out" << endl;
else if(price[s[3] - '1'] > money)
cout << "E008:Lack of balance" << endl;
else{
money -= price[s[3] - '1'];
goods[s[3] - '1']--;
cout << "S003:Buy success,balance=" << money << endl;
}
}
else
cout << "E006:Goods does not exist" << endl;
}
void back(){
int a = 0, b = 0, c = 0, d = 0;
if(money == 0)
cout << "E009:Work failure" << endl;
else{
d = money / 10;
if(d <= coins[3]){
money = money % 10;
coins[3] -= d;
}
else{
d = coins[3];
coins[3] = 0;
money -= d * 10;
}
c = money / 5;
if(c <= coins[2]){
money = money % 5;
coins[2] -= c;
}
else{
c = coins[2];
coins[2] = 0;
money -= d * 5;
}
b = money / 2;
if(b <= coins[1]){
money = money % 2;
coins[1] -= b;
}
else{
b = coins[1];
coins[1] = 0;
money -= d * 2;
}
a = money;
if(a <= coins[0]){
coins[0] -= a;
money = 0;
}
else{
coins[0] = 0;
money -= a;
}
cout << "1 yuan coin number=" << a << endl << "2 yuan coin number=" << b << endl << "5 yuan coin number=" << c << endl << "10 yuan coin number=" << d << endl;
}
}
void query(string& s){
if(s[1] == ' ' && s.length() == 3){
if(s[2] == 0){
vector<pair<pair<string, int>, int> > temp;
for(int i = 0; i < 6; i++)
temp.push_back(make_pair(make_pair("A" + char(i + 1), price[i]), goods[i]));
sort(temp.begin(), temp.end(), cmp);
for(int i = 0; i < 6; i++)
cout << temp[i].first.first << " " << temp[i].first.second << " " << temp[i].second << endl;
}
else if(s[2] == 1){
cout << "1 yuan coin number=" << coins[0] << endl
<< "2 yuan coin number=" << coins[1] << endl
<< "5 yuan coin number=" << coins[2] << endl
<< "10 yuan coin number=" << coins[3] << endl;
}
else
cout << "E010:Parameter error" << endl;
}
else
cout << "E010:Parameter error" << endl;
}
};
vector<string> split(string str, const char c){
vector<string> res;
istringstream iss(str);
string temp = "";
while(getline(iss, temp, c))
res.push_back(temp);
return res;
}
int main(){
string s;
while(getline(cin, s)){
Vending sale;
vector<string> orders = split(s, ';');
for(auto c: orders){
switch(c[0]){
case 'r':
sale.init(c);
break;
case 'p':
sale.pay(c);
break;
case 'b':
sale.buy(c);
break;
case 'c':
sale.back();
break;
case 'q':
sale.query(c);
break;
}
}
}
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)