今天终于有时间写博客了
蒟蒻前几天忙于订正题目。。。
今天题目比较简单所以才有时间来写博客。(昨天最后一题还没有搞懂。。km当初没学只学了匈牙利)
第一题
给你n根相同的木棍平均分给m个人
问木棍一共要分次。
这道题很简单,直接用gcd判断当分到第几个人时要不要切割。
n表示木棍根数
ns表示切到第几根木棍
m表示总人数
ms表示已经分的人数
所以如果ns/n==ms/m
那么就是给这个人分的时候不需要切割
所以就可以o(m)出解
代码
#include<cstdio>
#include<cstring>
int ans=0;
int n,m;
int gcd(int x,int y)
{
if(y==0)
{
return x;
}
else
{
return gcd(y,x%y);
}
}
int main()
{
freopen("kusac.in","r",stdin);
freopen("kusac.out","w",stdout);
scanf("%d %d",&n,&m);
int ns=1,ms=1;
int ans=0;
while(ms<=m)
{
while(((double)ms/m)>((double)ns/n))
{
ns++;
}
int gcdn=gcd(n,ns);
int gcdm=gcd(m,ms);
int nowns=ns/gcdn;
int nown=n/gcdn;
int nowms=ms/gcdm;
int nowm=m/gcdm;
if(nowns==nowms&&nown==nowm)
{
ms++;
}
else
{
ans++;
ms++;
}
}
printf("%d",ans);
return 0;
}
第二题
给你n个物品,有重量(w)和价值(v)
k个背包每个背包只能有一本书,且有限制重量(c)
我是这样做的
将n个物品按重量排序
将k个背包按限制重量排序
然后两个指针指着背包和物品的最前端(最小限制重量和最小重量)
然后我们从第一个背包开始
如果物品可以放入那么就将物品价值放进优先队列
直到物品不能再放入
然后将优先队列中最大的价值放到背包中
最后所有背包总价值就是答案
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int n,k;
struct thing
{
int w,v;
}t[300010];
int bag[300010];
bool cmp(thing a,thing b)
{
return a.w<b.w;
}
priority_queue <int,vector<int>,less<int> >q;
long long ans=0;
int main()
{
freopen("lopov.in","r",stdin);
freopen("lopov.out","w",stdout);
memset(t,0,sizeof(t));
memset(bag,0,sizeof(bag));
scanf("%d %d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d %d",&t[i].w,&t[i].v);
}
for(int i=1;i<=k;i++)
{
scanf("%d",&bag[i]);
}
sort(t+1,t+1+n,cmp);
sort(bag+1,bag+1+k);
int flagt=1;
int flagbag=1;
while(flagbag<=k)
{
while(t[flagt].w<=bag[flagbag]&&flagt<=n)
{
q.push(t[flagt].v);
flagt++;
}
if(!q.empty())
{
ans+=q.top();
q.pop();
}
flagbag++;
}
printf("%lld\n",ans);
return 0;
}
第三题
给你一个n*n的矩阵
让你在其中找出两个子矩阵
满足元素和一样
且仅有一个角相邻
类似于这样
1 1 0 0
1 1 0 0
0 0 1 1
0 0 1 1(忽略0)
1 2 0
2 3 0
0 0 8(忽略0)
于是我就想将每个矩阵和算出
以每个矩阵和为下标,记录下矩阵的左上角和右下角坐标
然后按不同的矩阵面积来处理
分别用四个二维数组来存有几个矩阵的四个角到达这里
(分别右下角、右上角、左下角、左上角)
然后n^2扫一遍就可以求出解了
代码
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int n;
int read[61][61];
int add[61][61];
struct piece
{
int x1,y1,x2,y2;
};
vector <piece> g[5000010];
vector <int> have;
int checkzs[61][61];
int checkrs[61][61];
int checkzx[61][61];
int checkrx[61][61];
bool used[5000010];
long long ans=0;
int main()
{
freopen("ratar.in","r",stdin);
freopen("ratar.out","w",stdout);
memset(read,0,sizeof(read));
memset(add,0,sizeof(add));
memset(used,0,sizeof(used));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&read[i][j]);
add[i][j]=read[i][j]+add[i-1][j]+add[i][j-1]-add[i-1][j-1];
}
}
for(int x1=1;x1<=n;x1++)
{
for(int y1=1;y1<=n;y1++)
{
for(int x2=x1;x2<=n;x2++)
{
for(int y2=y1;y2<=n;y2++)
{
int squre=add[x2][y2]+add[x1-1][y1-1]-add[x2][y1-1]-add[x1-1][y2]+2500000;
g[squre].push_back((piece){x1,y1,x2,y2});
if(used[squre]==0)
{
used[squre]=1;
have.push_back(squre);
}
}
}
}
}
for(int k=0;k<have.size();k++)
{
memset(checkzs,0,sizeof(checkzs));
memset(checkrs,0,sizeof(checkrs));
memset(checkzx,0,sizeof(checkzx));
memset(checkrx,0,sizeof(checkrx));
int now=have[k];
for(int i=0;i<g[now].size();i++)
{
checkzs[g[now][i].x1][g[now][i].y1]++;
checkrs[g[now][i].x1][g[now][i].y2]++;
checkzx[g[now][i].x2][g[now][i].y1]++;
checkrx[g[now][i].x2][g[now][i].y2]++;
}
for(int x=1;x<=n;x++)
{
for(int y=1;y<=n;y++)
{
if(checkrx[x][y]&&checkzs[x+1][y+1])
{
ans+=checkrx[x][y]*checkzs[x+1][y+1];
}
if(checkzx[x][y]&&checkrs[x+1][y-1])
{
ans+=checkzx[x][y]*checkrs[x+1][y-1];
}
}
}
}
printf("%lld\n",ans);
return 0;
}
然而由于玄学
我的这个程序在评测是满分
自己数据测要一点几秒
别人数据测要两秒
oj上测也要一点二秒。。。
stl的劣根性(vector)
可以用链表代替
flag:我就是饿死,从这里跳下去,死外边,也不用stl了!
真香!!