1. 双核处理
一种双核CPU的两个核能够同时的处理任务,现在有n个已知数据量的任务需要交给CPU处理,假设已知CPU的每个核1秒可以处理1kb,每个核同时只能处理一项任务。n个任务可以按照任意顺序放入CPU进行处理,现在需要设计一个方案让CPU处理完这批任务所需的时间最少,求这个最小的时间。
分类:动态规划问题
#include <iostream>
#include <string>
using namespace std;
int minTime(int n, int* length)
{
int* temp = new int[n];
int sum = 0;
for (int i = 0; i < n; i++)
{
temp[i] = length[i]/1024;
sum += temp[i];
}
int* dp = new int[int(sum/2)+1];
memset(dp,0,sizeof(int)*(int(sum/2)+1));
dp[0] = 1;
for (int i = 0; i < n; i++)
{
for (int j = int(sum/2) - temp[i]; j >= 0; j--)
{
if (dp[j] && !dp[j+temp[i]])
dp[j+temp[i]] = 1;
}
}
int i = int(sum/2);
while(dp[i] == 0&&i>0)
i--;
return (sum-i)*1024;
}
int main()
{
int n;
cin>>n;
int* length = new int[n];
for (int i = 0; i < n; i++)
{
cin>>length[i];
}
cout<<minTime(n, length);
return 0;
}
2. 赶去公司
终于到周末啦!小易走在市区的街道上准备找朋友聚会,突然服务器发来警报,小易需要立即回公司修复这个紧急bug。假设市区是一个无限大的区域,每条街道假设坐标是(X,Y),小易当前在(0,0)街道,办公室在(gx,gy)街道上。小易周围有多个出租车打车点,小易赶去办公室有两种选择,一种就是走路去公司,另外一种就是走到一个出租车打车点,然后从打车点的位置坐出租车去公司。每次移动到相邻的街道(横向或者纵向)走路将会花费walkTime时间,打车将花费taxiTime时间。小易需要尽快赶到公司去,现在小易想知道他最快需要花费多少时间去公司。
分类:普通编程
#include<iostream>
using namespace std;
int getDistance(int x1, int y1, int x2, int y2) {
return abs(x1-x2) + abs(y1-y2);
}
int minTime(int* tX, int* tY, int n, int gx, int gy, int walkTime, int taxiTime) {
int minTime = getDistance(0,0,gx,gy)*walkTime;
for (int i = 0; i < n; i++){
int tmp = getDistance(0,0,tX[i],tY[i])*walkTime + getDistance(tX[i],tY[i],gx,gy)*taxiTime;
if (minTime > tmp) {
minTime = tmp;
}
}
return minTime;
}
int main(){
int n;
cin>>n;
int* tX = new int[n];
int* tY = new int[n];
int gx,gy;
int walkTime,taxiTime;
for (int i = 0; i < n; i++){
cin>>tX[i];
}
for (int i = 0; i < n; i++){
cin>>tY[i];
}
cin>>gx>>gy;
cin>>walkTime>>taxiTime;
cout<<minTime(tX,tY,n,gx,gy,walkTime,taxiTime);
return 0;
}
3. 调整队形
在幼儿园有n个小朋友排列为一个队伍,从左到右一个挨着一个编号为(0~n-1)。其中有一些是男生,有一些是女生,男生用'B'表示,女生用'G'表示。小朋友们都很顽皮,当一个男生挨着的是女生的时候就会发生矛盾。作为幼儿园的老师,你需要让男生挨着女生或者女生挨着男生的情况最少。你只能在原队形上进行调整,每次调整只能让相邻的两个小朋友交换位置,现在需要尽快完成队伍调整,你需要计算出最少需要调整多少次可以让上述情况最少。例如:
GGBBG -> GGBGB -> GGGBB
这样就使之前的两处男女相邻变为一处相邻,需要调整队形2次
分类:字符串处理
#include <iostream>
#include <string>
using namespace std;
int remove(const string& s, char ch)
{
string str = s;
int count = 0;
string::size_type i = 0;
while (i < str.size())
{
if (str[i] == ch)
{
i++;
continue;
}
string::size_type j = i;
while (j < str.size() && str[j] != ch)
j++;
if (j == str.size())
return count;
else
{
count += j - i;
str[i] = (ch == 'G')?'G':'B';
str[j] = (ch == 'G')?'B':'G';
}
i++;
}
return count;
}
int main()
{
string s;
cin>>s;
int count = min(remove(s,'G'),remove(s,'B'));
cout<<count<<endl;
return 0;
}
4.消除重复元素
小易有一个长度为n序列,小易想移除掉里面的重复元素,但是小易想是对于每种元素保留最后出现的那个。小易遇到了困难,希望你来帮助他。
分类:普通编程
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void deleteElem(int* sequence, int n){
typedef struct elem
{
int num;
int flag;
}elemType;
vector<elemType> vec;
for (int i = 0; i < n; i++){
vector<elemType>::iterator it = vec.begin();
for (; it != vec.end(); it++){
if (it->num == sequence[i]) {
it->flag = 0;
}
}
elemType tmp = {sequence[i],1};
vec.push_back(tmp);
}
vector<elemType>::iterator it = vec.begin();
vector<int> new_vec;
for (; it != vec.end(); it++){
if (it->flag == 1)
new_vec.push_back(it->num);
}
for (int i = 0; i < new_vec.size()-1; i++){
cout<<new_vec[i]<<" ";
}
cout<<new_vec.back();
}
int main() {
int n;
cin>>n;
int* sequence = new int[n];
for (int i = 0; i < n; i++){
cin>>sequence[i];
}
deleteElem(sequence,n);
return 0;
}
6. 工作分配
现在有n位工程师和6项工作(编号为0至5),现在给出每个人能够胜任的工作序号表(用一个字符串表示,比如:045,表示某位工程师能够胜任0号,4号,5号工作)。现在需要进行工作安排,每位工程师只能被安排到自己能够胜任的工作当中去,两位工程师不能安排到同一项工作当中去。如果两种工作安排中有一个人被安排在的工作序号不一样就被视为不同的工作安排,现在需要计算出有多少种不同工作安排计划。
分类:回溯递归
#include <iostream>
#include <vector>
#include <string>
using namespace std;
static int count = 0;
const int engineerNum = 6;
void generator(vector<vector<int>> jobs, bool flag[], int index, int n){
if (index == n){
count++;
return;
}
vector<int> job = jobs[index];
vector<int>::iterator it = job.begin();
for (; it < job.end(); it++){
if (!flag[(*it)]){
flag[(*it)] = true;
generator(jobs,flag,index+1,n);
flag[(*it)] = false;
}
}
}
int main() {
int n;
cin>>n;
vector<vector<int>> jobs;
for (int i = 0; i < n; i++){
vector<int> vec;
string job;
cin>>job;
for (int j = 0; j < job.size(); j++){
vec.push_back(job[j]-'0');
}
jobs.push_back(vec);
}
bool flag[6] = {false};
generator(jobs,flag,0,n);
cout<<count;
return 0;
}
7. 集合
小易最近在数学课上学习到了集合的概念,集合有三个特征:1.确定性
2.互异性 3.无序性.
小易的老师给了小易这样一个集合:
S = { p/q | w ≤ p ≤ x, y ≤ q ≤ z }
需要根据给定的w,x,y,z,求出集合中一共有多少个元素。小易才学习了集合还解决不了这个复杂的问题,需要你来帮助他。
分类:普通编程
#include<iostream>
#include<cstring>
#include<set>
using namespace std;
struct Frac{
int p,q;
bool operator<(const Frac &frac)const{
if(this->p!=frac.p)
return p<frac.p;
if(this->q!=frac.q)
return q<frac.q;
return false;
}
};
int gcd(int a,int b){
if (a < b)
return gcd(b,a);
if (a%b == 0)
return b;
return gcd(b,a%b);
}
int main(){
int w,x,y,z;
set<Frac>s;
cin>>w>>x>>y>>z;
Frac f;
for(int i=w;i<=x;i++){
for(int j=y;j<=z;j++){
int div=gcd(i,j);
f.p=i/div;
f.q=j/div;
s.insert(f);
}
}
cout<<s.size()<<endl;
}
8.
奇怪的表达式
常规的表达式求值,我们都会根据计算的优先级来计算。比如*/的优先级就高于+-。但是小易所生活的世界的表达式规则很简单,从左往右依次计算即可,而且小易所在的世界没有除法,意味着表达式中没有/,只有(+, - 和 *)。现在给出一个表达式,需要你帮忙计算出小易所在的世界这个表达式的值为多少
分类:普通编程
#include<iostream>
#include<string>
using namespace std;
int main(){
string expression;
cin>>expression;
int flag = 0;
int tmp;
for (int i = 2; i < expression.size(); i += 2){
int left = flag?tmp:(expression[i-2] - '0');
int right = expression[i] - '0';
char op = expression[i-1];
if (op == '+')
tmp = left + right;
if (op == '-')
tmp = left - right;
if (op == '*')
tmp = left * right;
flag = 1;
}
cout<<tmp;
return 0;
}
9.涂棋盘
小易有一块n*n的棋盘,棋盘的每一个格子都为黑色或者白色,小易现在要用他喜欢的红色去涂画棋盘。小易会找出棋盘中某一列中拥有相同颜色的最大的区域去涂画,帮助小易算算他会涂画多少个棋格。
分类:
动态规划
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<char> getMaxtrixCol(vector<vector<char>> chess, int i){
vector<char> col;
for (vector<vector<char>>::iterator it = chess.begin(); it != chess.end(); it++){
col.push_back((*it)[i]);
}
return col;
}
int getMaxCount(vector<char> col_vec){
int length = col_vec.size();
int* dp = new int[length+1];
memset(dp,0,sizeof(int)*(length+1));
char current = 'B';
for (int i = 1; i <= length; i++){
if (col_vec[i-1] == current)
dp[i] = dp[i-1]+1;
else
dp[i] = 1;
current = col_vec[i-1];
}
int max = -1;
for (int i = 1; i <= length; i++){
if (dp[i] > max)
max = dp[i];
}
return max;
}
int main(){
int n;
cin>>n;
vector<vector<char>> chess;
for (int i = 0; i < n; i++){
vector<char> row_vec;
string row;
cin>>row;
for (int j = 0; j < n; j++){
row_vec.push_back(row[j]);
}
chess.push_back(row_vec);
}
int max = -1;
vector<char> col_vec;
for (int i = 0; i < n; i++){
col_vec = getMaxtrixCol(chess,i);
int count = getMaxCount(col_vec);
if (max < count)
max = count;
}
cout<<max;
return 0;
}
10.记单词
小易参与了一个记单词的小游戏。游戏开始系统提供了m个不同的单词,小易记忆一段时间之后需要在纸上写出他记住的单词。小易一共写出了n个他能记住的单词,如果小易写出的单词是在系统提供的,将获得这个单词长度的平方的分数。注意小易写出的单词可能重复,但是对于每个正确的单词只能计分一次。
分类:普通编程
#include <iostream>
#include <vector>
#include <string>
#include <set>
using namespace std;
int getScore(set<string> set1,set<string> set2){
int score = 0;
set<string>::iterator it = set1.begin();
for (; it != set1.end(); it++){
if (set2.find(*it) != set2.end())
score += ((*it).size())*((*it).size());
}
return score;
}
int main(){
int n,m;
cin>>n>>m;
set<string> remember,system;
for (int i = 0; i < n; i++){
string word;
cin>>word;
remember.insert(word);
}
for (int i = 0; i < m; i++){
string word;
cin>>word;
system.insert(word);
}
cout<<getScore(remember,system);
return 0;
}