题目链接:http://codeforces.com/gym/101572
B题
题意:给你n个人的第一棒的速度和其他棒的速度,然后让你输出最快的那个组合,输出时间和人。
思想:模拟
D题
题意:给你n个01串代表每个人的特征,现在让你求一个和他们长度相等但是和他们相似度最对的那个串。
思想:考虑最短路问题,将每个串拆出来k个差一位的子串,然后每个串开始不断的取反某一位,最后找到一个取反最多的。输出即可。
#include
using namespace std;
const int maxn = 1e5+5;
char str[30];
int dist[1<<20];
int main()
{
queueq;
memset(dist,-1,sizeof(dist));
int n,k;
scanf("%d%d",&n,&k);
for(int i=0;imaxx)
{
maxx=dist[T];
ans=T;
}
}
}
for(int i=0;i
E题
题意:给你一个n*m的图,每个点有一个权值 小于0为水高于0为干旱的地,现在将抽水机放到一个位置问你最多能抽多少水,直接bfs抽水机的点,比当前点小的变到跟当前一样大,因为最多抽到跟当前点一样多的水。
#include
using namespace std;
typedef long long ll;
const int maxn=5e2+10;
int vis[maxn][maxn];
ll Map[maxn][maxn];
ll dis[maxn][maxn];
int dir[8][2]={-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};
struct node{
int x;
int y;
ll valu;
bool operator <(const node &a) const{
return valu > a.valu;
}
};
int main()
{
int h,w;
int x,y;
scanf("%d%d",&h,&w);
for(int i=1;i<=h;i++)
for(int j=1;j<=w;j++)
scanf("%lld",&Map[i][j]);
scanf("%d%d",&x,&y);
priority_queueq;
q.push(node{x,y,Map[x][y]});
vis[x][y]=1;
dis[x][y]=Map[x][y];
while(!q.empty())
{
node u=q.top();
q.pop();
for(int i=0;i<8;i++)
{
int xx=dir[i][0]+u.x;
int yy=dir[i][1]+u.y;
if(xx>=1 && xx<=h && yy>=1 && yy<=w && vis[xx][yy]==0 && Map[xx][yy] < 0)
{
vis[xx][yy]=1;
ll T = max(u.valu,Map[xx][yy]);
dis[xx][yy]=T;
q.push(node{xx,yy,T});
}
}
}
ll ans=0;
for(int i=1;i<=h;i++)
for(int j=1;j<=w;j++)
ans+=(-1)*dis[i][j];
printf("%lld\n",ans);
return 0;
}
G题
题意:给你n个队伍,m个过题记录。m行是某个队伍过了题然后的罚时。输出m行每次有人过题之后,1队的排名
思想:树状数组维护即可。树状数组维护当前点过题的人数。
#include
using namespace std;
const int maxn = 1e5+5;
struct node{
int x;
int y;
}no[maxn];
int team[maxn];
int score[maxn];
int sum[maxn];
pairP[2*maxn];
int n,m,cnt;
void add(int x,int valu)
{
while(x<=cnt)
{
sum[x]+=valu;
x+=(x&(-x));
}
}
int ask(int x)
{
int ans=0;
while(x>0)
{
ans+=sum[x];
x-=(x&(-x));
}
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
P[cnt++]=make_pair(0,0);
for(int i=0;i
I题
题意:求一个有向图的最小环,输出路径。
思想:Floyd求最小环即可
J题
题意:给你n,m代表2遍的牙齿数量,问你牙齿总数或者是没有牙齿。
思想:模拟即可 特判下0 0
K题
题意:给你b,n,e代表三类人,分别是慢的中速快的,然后给你每个人的速度,然后给你(b+n+e)/2个皮划艇的速度系数,一个皮划艇的速度=皮划艇的速度系数*(第一个的速度+第二个的速度)
思想:二分+贪心
#include
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define scanf(a) scanf("%d",&a);
using namespace std;
const double eps = 1e-7;
const int maxn=1e5+5;
int a[maxn];
int b,n,e,m,sb,sn,se;
struct node{
int x;
int y;
int z;
int value;
bool operator < (const node &a)const {
return value < a.value;
}
}no[maxn];
int check(int mid)
{
int bb=b,nn=n,ee=e;
rep(i,1,m)
{
int cnt=0;
double temp = (double)(mid) / (double)a[i];
if(bb>=2)
no[cnt++]={2,0,0,sb+sb};
if(nn>=2)
no[cnt++]={0,2,0,sn+sn};
if(ee>=2)
no[cnt++]={0,0,2,se+se};
if(bb && nn)
no[cnt++]={1,1,0,sb+sn};
if(bb && ee)
no[cnt++]={1,0,1,sb+se};
if(nn && ee)
no[cnt++]={0,1,1,sn+se};
sort(no,no+cnt);
int flag=0;
rep(j,0,cnt-1)
{
if(temp - (double)(no[j].value) <= eps)
{
flag=1;
bb=bb-no[j].x;
nn=nn-no[j].y;
ee=ee-no[j].z;
break;
}
}
if(flag==0)
return 0;
}
return 1;
}
int main()
{
scanf(b);
scanf(n);
scanf(e);
m = (b+n+e)/2;
scanf(sb);
scanf(sn);
scanf(se);
rep(i,1,m)
scanf(a[i]);
int l=1;
int r=1e9;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))
l=mid+1;
else
r=mid-1;
}
printf("%d\n",r);
return 0;
}
用ll也是OK的