前三题早就写好了,一直在纠结D
A. Jzzhu and Children
题意:就是简单的模拟,给排成一队的孩子分发糖果,每个孩子有至少要得到的糖果数。
然后每次给队头的孩子分发m个糖果,如果他已经得到了足够的糖果(大于等于他想得到的
最少糖果数)那么他就出队,否则他就去队尾。问最后一个孩子的编号。
算法:队列模拟,水题~
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
struct node
{
int v,id;
};
queue<node> q;
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
while(!q.empty()) q.pop();
node cur;
for(int i=1;i<=n;i++)
{
scanf("%d",&cur.v);
cur.id = i;
q.push(cur);
}
int flag = 0;
while(!q.empty())
{
if(q.size()==1)
flag = 1;
node x,next;
x = q.front();
q.pop();
if(flag==1)
{
printf("%d\n",x.id);
break;
}
int t = x.v-m;
if(t>0)
{
next.v = t;
next.id = x.id;
q.push(next);
}
}
}
return 0;
}
B. Jzzhu and Sequences
题意: 现在输入x和y,求fn%1000000007 (109 + 7)。
算法:
就是找到一个循环节
f(i) = f(i-1) - f(i-2)
f(i+1) = -f(i-2)
f(i+2) = -f(i-1)
f(i+3) = f(i-2) - f(i-1)
f(i+4) = f(i-2)
f(i+5) = f(i-1)
f(i+6) = f(i-1) - f(i-2) = f(i)
以6为一个循环周期。
注意输入x 和 y 时就要处理>mod则 %mod,小于mod 则+mod后再模mod。避免后面溢出。
注意n = 1 和2 的时候直接输出。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
const ll mod = 1000000007LL ;
ll a[10];
ll f1,f2,n;
int main()
{
while(scanf("%I64d%I64d",&f1,&f2)!=EOF)
{
scanf("%I64d",&n);
int x = 0;
if(f1>mod) f1%=mod;
if(f1<0) f1 = (f1+mod)%mod;
if(f2>mod) f2%=mod;
if(f2<0) f2 = (f2+mod)%mod;
a[x++] = f2-f1;
a[x++] = -f1;
a[x++] = -f2;
a[x++] = f1-f2;
a[x++] = f1;
a[x++] = f2;
for(int i=0;i<x;i++)
{
if(a[i]<0)
a[i] = (a[i]+mod)%mod;
}
if(n==1)
printf("%I64d\n",f1);
else if(n==2)
printf("%I64d\n",f2);
else{
int t = (n-3)%x;
printf("%I64d\n",a[t]);
}
}
return 0;
}
C. Jzzhu and Chocolate
题意:
把一块n*m格的巧克力切k刀,每次只能沿着横线和竖线切,不能一格分成两部分。如果不能切k刀,输出-1.如果能,
问k刀后,最小的那块巧克力最多含有多少个格子。
算法:
1、一块n*m的巧克力最多能切n-1+m-1即n+m-2刀,如果k>n+m-2则输出-1.
2、由(n/3)*m>(n/2)*(m/2)即把一边切两刀比两边各切一刀得到的面积大,得到贪心策略:如果一边能切,
尽量先切一边再切另一边。
但是先切哪一边使得结果最优呢,两种情况分别计算取最大值就好。
P.S:突然发现,这题的程序和#32的那道神题的错误代码一模一样的思路呢,用这种思路过了那题的人们,
OMG!!!
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
ll n,m,k,s1,s2;
int main()
{
while(scanf("%I64d%I64d%I64d",&n,&m,&k)!=EOF)
{
if(k > n+m-2)
{
printf("-1\n");
continue;
}
if(k<=m-1)
s1 = n*(m/(k+1));
else
s1 = n/(k-m+2);
if(k<=n-1)
s2 = m*(n/(k+1));
else
s2 = m/(k-n+2);
printf("%I64d\n",max(s1,s2));
}
return 0;
}
D. Jzzhu and Cities
题意:明天早上来写,今天要回去了。。。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define maxm 300010
#define maxn 100010
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
struct E
{
int to,next;
ll w;
}e[maxm<<2];
int head[maxn],cnt,n,c[maxn],mp[maxn];
bool vis[maxn];
ll dis[maxn];
priority_queue<int> q;
void init()
{
memset(mp,0x3f,sizeof(mp));
memset(c,0,sizeof(c));
memset(vis,0,sizeof(vis));
memset(head,-1,sizeof(head));
cnt = 0;
}
void add(int x,int y,ll z)
{
e[cnt].to = y;
e[cnt].w = z;
e[cnt].next = head[x];
head[x] = cnt++;
e[cnt].to = x;
e[cnt].w = z;
e[cnt].next = head[y];
head[y] = cnt++;
}
void spfa()
{
for(int i=1;i<=n;i++)
dis[i] = INF;
while(!q.empty())
q.pop();
dis[1] = 0;
c[1] = 1;
q.push(1);
vis[1] = true;
while(!q.empty())
{
int u = q.top();
q.pop();
vis[u] = 0;
for(int k = head[u];k!=-1;k=e[k].next)
{
int v = e[k].to;
if(dis[v]>dis[u]+e[k].w)
{
dis[v] = dis[u]+e[k].w;
c[v] = c[u];
if(!vis[v])
{
q.push(v);
vis[v] = true;
}
}
else if(dis[v]==dis[u]+e[k].w)
{
c[v]+=c[u];
if(c[v]>2) c[v] = 2;
}
}
}
}
int main()
{
int u,v,m,k,s,y,sum;
ll w;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
init();
for(int i=0;i<m;i++)
{
scanf("%d%d%I64d",&u,&v,&w);
add(u,v,w);
}
for(int i=0;i<k;i++)
{
scanf("%d%d",&s,&y);
if(mp[s]>y)
mp[s] = y;
}
sum = 0;
for(int i=1;i<=n;i++)
{
if(mp[i]!=INF)
{
add(1,i,mp[i]);
sum++;
}
}
spfa();
for(int i=1;i<=n;i++)
{
if(mp[i]!=INF)
{
if(dis[i]<mp[i])
sum--;
else if(dis[i]==mp[i] && c[i]>1)
sum--;
}
}
printf("%d\n",k-sum);
}
return 0;
}