A:Jzzhu and Chocolate
直接横切或者竖切,如果不行,再两者混合切。
#include <stdio.h> #include <string.h> #include<iostream> using namespace std; #define LL __int64 int main() { int n,m,k; while(~scanf("%d%d%d",&n,&m,&k)) { LL ans; if(n>m)swap(n,m); if(n+m-2<k)cout<<"-1"<<endl; else { if(m<=k+1)cout<<max(m/(k-n+1+1),n/(k-m+1+1))<<endl; else if(n<=k+1) { cout<<max(m/(k-n+2),n*(m/(k+1)))<<endl; } else { ans=(LL)n*(m/(k+1)); ans=max(ans,(LL)m*(n/(k+1))); cout<<ans<<endl; } } } return 0; }
B:Jzzhu and Cities
把train route 当成正常的路径。然后用dij求最短路。如果当前点的最短路不是由train route 求过来的。
那么到这个点的train route 就是无效的。
#include <stdio.h>
#include <string.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
#define LL __int64
#define maxn 110000
#define INF (LL)1000000009
struct list
{
int u,v,next;
LL w;
int leap;
}node[maxn*8];
int head[maxn];
int num;
LL dist[maxn];
int ans;
void add(int u,int v,LL w,int leap)
{
node[num].v=v;
node[num].w=w;
node[num].next=head[u];
node[num].leap=leap;
head[u]=num++;
}
struct nodes
{
int u;
LL w;
int leap;
friend bool operator <(const nodes &a,const nodes &b)
{
if(a.w!=b.w)return a.w>b.w;
else return a.leap>b.leap;
}
}p,pp;
priority_queue<nodes>que;
int vis[maxn];
int n,m,k;
void dos()
{
memset(vis,0,sizeof(vis));
while(!que.empty())que.pop();
p.u=1;
p.w=0;
p.leap=0;
que.push(p);
while(!que.empty())
{
p=que.top();
que.pop();
int u=p.u;
if(vis[u])continue;
vis[u]=1;
if(p.leap==0&&dist[u]!=-1)
{
ans++;
}
else
{
// cout<<u<<" "<<dist[u]<<p.leap<<" "<<p.w<<endl;
}
for(int i=head[u];i!=-1;i=node[i].next)
{
if(vis[node[i].v])continue;
pp.u=node[i].v;
pp.w=node[i].w+p.w;
pp.leap=node[i].leap;
que.push(pp);
}
}
cout<<ans<<endl;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&k))
{
memset(dist,-1,sizeof(dist));
memset(head,-1,sizeof(head));
num=1;
int u,v;
LL w;
ans=0;
for(int i=1;i<=m;i++)
{
scanf("%d%d%I64d",&u,&v,&w);
add(u,v,w,0);
add(v,u,w,0);
}
for(int i=1;i<=k;i++)
{
scanf("%d%I64d",&u,&w);
if(dist[u]==-1)dist[u]=w;
else
{
dist[u]=min(dist[u],w);
ans++;
}
}
for(int i=1;i<=n;i++)
{
if(dist[i]!=-1)
{
add(1,i,dist[i],1);
}
}
dos();
}
return 0;
}
C:Jzzhu and Apples
直接模拟啊。。。
首先对于奇数,把对于当前奇数的+2倍放起来,然后可以任意两个组合。
最后如果剩余一个,那么直接2倍就好。
偶数任意两个搭配。
#include <stdio.h>
#include <string.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
#define LL __int64
#define maxn 110000
#define INF (LL)1000000009
vector<pair<int,int> >vec;
vector<int>as;
int vis[maxn];
int main()
{
int n;
while(~scanf("%d",&n))
{
memset(vis,0,sizeof(vis));
vec.clear();
for(int i=3;i<=n;i+=2)
{
if(vis[i])continue;
as.clear();
for(int j=i;j<=n;j+=i*2)
{
if(vis[j])continue;
as.push_back(j);
}
if(as.size()==0)continue;
for(int j=as.size()-2;j>=0;j-=2)
{
vec.push_back(make_pair(as[j],as[j+1]));
vis[as[j]]=vis[as[j+1]]=1;
}
if(as.size()&1)
{
if(i*2>n)continue;
vec.push_back(make_pair(i,i*2));
vis[i]=vis[i*2]=1;
}
}
as.clear();
for(int i=2;i<=n;i+=2)
{
if(vis[i])continue;
as.push_back(i);
}
for(int j=1;j<as.size();j+=2)
{
vec.push_back(make_pair(as[j],as[j-1]));
}
cout<<vec.size()<<endl;
for(int i=0;i<vec.size();i++)
{
cout<<vec[i].first<<" "<<vec[i].second<<endl;
}
}
return 0;
}