一、双核处理
本题目是0-1背包的变种,题目的目标是求最少需要处理的时间。可以将目标转化为在 总任务长度/2的时间内,一个CPU最多能处理的任务量,那么答案为 总任务量-在总任务长度/2的时间内最多工作量。 因为工作时间的理想最小值为总任务长度/2,那么如果一个cpu的处理时间大于总任务长度/2,那么另外一个CPU就必然小于总任务长度/2。目标实际上就转化为处理少的那个CPU尽量逼近理想值。
代码如下:
#include
using namespace std;
const int maxn = 55;
const int maxh=4096*26;
int d[2][maxh];
int main()
{
int n,a[maxn],sum=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
a[i]/=1024;
sum+=a[i];
}
for(int i=n;i>0;i--)
for(int j=0;j<=sum/2;j++)
{
d[i&1][j]=(i==n?0:d[(i+1)&1][j]);
if(j>=a[i])
d[i&1][j]=max(d[i&1][j],d[(i+1)&1][j-a[i]]+a[i]);
}
int ans = max (d[1][sum/2],sum-d[1][sum/2]);
cout<
二、赶去公司
本题目直接枚举出各种情况下的值,就可以得到答案。
代码如下:
#include
using namespace std;
const int maxn=10000+100;
int computedis(int x1,int y1,int x2,int y2)
{
return abs(x1-x2)+abs(y1-y2);
}
int main()
{
int n,tx[maxn],ty[maxn],gx,gy,walktime,taxitime,ans;
cin>>n;
for(int i=0;i>tx[i];
for(int i=0;i>ty[i];
cin>>gx>>gy;
cin>>walktime>>taxitime;
ans=computedis(0,0,gx,gy)*walktime;
for(int i=0;itmp)
ans=tmp;
}
cout<
本题目可以设想两种情况一种为G开通,一种为B开头。比如GGBGG,需要移动后面两个到前面,实际上一个G的移动次数等于G中间B的个数,上面例子中有2个G要移动B的个数为1,那么2*1=2.只需要两次就能调整完。
代码如下:
#include
using namespace std;
int main()
{
//freopen("datain.txt","r",stdin);
string s;
cin>>s;
char start;
start = s[0];
int cnt=0,ans=0,ans2=0;
int i=1;
while(start==s[i]) i++;
for(;ians)
cout<
四、消除重复元素
本题可以构建一个结构体存储数字的值和位置,通过值来判断重复,通过位置来帮助输出。
#include
using namespace std;
const int maxn=1000+10;
struct num
{
int value;
int pos;
bool operator < (const num n1) const{
return pos< n1.pos;
}
};
int main()
{
int n,len=0;
num num1[maxn];
cin>>n;
for(int i=0;i>x;
for(int j=0;j
五、魔力手环
本题目因为计算量太大,不能直接枚举。采用快速幂矩阵的方式,进行状态的快速变换。具体可以参考点击打开链接,通过将每次状态变化,转换成矩阵的乘法,通过矩阵运算来降低算法的复杂度。
代码如下:
#include
using namespace std;
//构建快速幂矩阵
const int maxn=50+10;
int ans[maxn];
int anspre[maxn];
int fast[maxn][maxn];
int fastpre[maxn][maxn];
int n,k;
int compute(int i,int j,int fast[maxn][maxn])
{
int sum=0;
for(int k=0;k>n>>k;
for(int i=0;i>ans[i];
}
for(int i=0;i>1;
for(int i=0;i
六、工作安排
因为工作只有6种,那么直接枚举可能就行。
代码如下:
#include
using namespace std;
const int maxn = 10;
int n,work[maxn][maxn],ans=0;
bool judge(int *A)
{
int flag=true;
for(int i=0;i>n;
for(int i=0;i>s;
for(int j=0;j
七、集合
本题也是采取暴力方式求解,使用map存储已经获得的元素,避免重复输出。
#include
using namespace std;
int main()
{
map mp1;
int w,x,y,z,ans=0;
cin>>w>>x>>y>>z;
for(int i=w;i<=x;i++)
for(int j=y;j<=z;j++)
{
double tmp=(double)i/j;
if(!mp1.count(tmp))
{
ans++;
mp1[tmp]=1;
}
}
cout<
八、奇怪的表达式求值
本题目采用1个双端队列存储操作数,1个队列存储操作符,就能满足题目要求。
代码如下:
#include
using namespace std;
int main()
{
deque dq1;
deque dq2;
string s;
cin>>s;
for(int i=0;i
九、涂棋盘
根据题目数格子就行。
#include
using namespace std;
const int maxn = 50+10;
int main()
{
int n;
char G[maxn][maxn];
cin>>n;
for(int i=0;i>s;
for (int j=0;j
本题目使用map来存储准确答案,当输入的答案存在map中的时候,得分。否则不得分。
#include
using namespace std;
const int maxn=60;
int main()
{
//freopen("datain.txt","r",stdin);
map mp;
string ans[maxn];
int n,m,res=0;
cin>>n>>m;
for(int i=0;i>ans[i];
}
for(int i=0;i>s;
mp[s]=1;
}
for(int i=0;i
十一、堆砖块
本题目使用动态规划,需要将优化目标进行转换,具体可以参考点击打开链接,采用动态规划的时候,可能出现空间不够的情况,参考链接中的方法直接使用 &1 的方式,也就是滚动数组的方式,值得学习。另外一种是采用枚举+剪枝。这个方法也理解比动态规划简单。
十二、分饼干
本题目,直接枚举只有50%的通过率。因为取余运算可以这样表示 1120%7=(1000%7+100%7+20%7+0%7)%7,那么采用d[i][j]表示在前i位后,余数为j的数量。当位数不为X的时候,数量不会增加,但是会转移,比如前2为时候余数1的数量为1,第3位不为X的话,那么余数1的那个数量1可能会转移到余数2等等。当为X的时候,数量会转移也会增加。
#include
using namespace std;
const int maxn=20;
const int maxm=100000;
long long d[maxn][maxm];
int main()
{
//freopen("datain.txt","r",stdin);
long long n;
string s;
cin>>s;
cin>>n;
int tmp1=(long long)((s[0]-'0')*pow(10,s.length()-1))%n;
d[1][tmp1]=1;
for(int i=1;i