群赛地址:
https://vjudge.net/contest/186412#problem
A - Jzzhu and Children
CodeForces - 450A题意:一个小孩序列,为每个小孩需要的糖数.一人从第一个小孩开始给糖,每次给k个.求最后一个拿糖的小孩编号.
题解:
#include<iostream>
using namespace std;
int main(){
int n,m,a[110],done[110]={0},last;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i];
bool b=1;
while(b){
b=0;
for(int i=1;i<=n;i++){
if(!done[i]){
last=i;
b=1;
a[i]-=m;
if(a[i]<=0)done[i]=1;
}
}
}
cout<<last;
}
B - Jzzhu and Sequences
CodeForces - 450B题意:一个序列,a[i]=a[i-1]-a[i-2],求数列第n项模1e9+7.
题解:
#include<iostream>
using namespace std;
const int M=1e9+7;
int main(){
long long a,b,n;
cin>>a>>b>>n;
n%=6;
switch(n){
case 1:cout<<(a+M)%M;break;
case 2:cout<<(b+M)%M;break;
case 3:cout<<(b-a+2*M)%M;break;
case 4:cout<<(-a+M)%M;break;
case 5:cout<<(-b+M)%M;break;
case 0:cout<<(a-b+2*M)%M;break;
}
}
C - Jzzhu and Chocolate CodeForces - 450C
思路:要么全切一边,要么一边切完了切另一边.
题解:
#include<iostream>
#include<algorithm>
using namespace std;
long long n,m,k,ans;
int main(){
cin>>n>>m>>k;
if(n<m)swap(n,m);
if(k<n)ans=max(n*(m/(k+1)),m*(n/(k+1)));
else ans=max(n/(k-m+2),m/(k-n+2));
if(ans==0)ans=-1;
cout<<ans;
}
D - Jzzhu and Cities
CodeForces - 450D
题意:一张无向连通图,0点是首都,有k条铁路连着0与其他点,求最多能撤去的铁路数使首都到各地的距离不变.
思路:dijkstra优先队列优化,当铁路的边被替换时,ans++;
失败的代码:
#include<stdio.h>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
typedef pair<int,int> pii;
const int maxn=100010;
const int inf=1e9+7;
struct Dijkstra{
int n,m;
vector<pii>G[maxn];
bool done[maxn];
int d[maxn];
void init(int n,int m){
this->n=n;
this->m=m;
for(int i=0;i<n;i++) G[i].clear();
}
void AddEdge(int from,int to,int dist){
G[from].push_back(pii{dist,to});
G[to].push_back(pii{dist,from});
}
void dijkstra(int s){
priority_queue<pii,vector<pii>,greater<pii> >q;
for(int i=1;i<=n;i++) d[i]=inf;
d[s]=0;
memset(done,0,sizeof(done));
q.push(pii{0,s});
while(!q.empty()){
pii x=q.top();q.pop();
int &u=x.second;
// printf("top:pii(%d %d) {\n",x.first,x.second);
if(done[u])continue;
done[u]=true;
for(int i=0;i<G[u].size();i++){
int &e=G[u][i].second;
// printf(" pii:(%d %d)",G[u][i].first,e);
if(done[e])continue;
if(d[e]>d[u]+G[u][i].first){
d[e]=d[u]+G[u][i].first;
q.push(G[u][i]);
// printf("->in");
}
// printf("\n");
}
// printf("}\n");
}
}
};
int main(){
Dijkstra DJ;
int n,m,k,a,b,c,ans=0;
scanf("%d%d%d",&n,&m,&k);
DJ.init(n,m);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
DJ.AddEdge(a,b,c);
DJ.AddEdge(b,a,c);
}
DJ.dijkstra(1);
// for(int i=1;i<=DJ.n;i++){
// printf("%d ",DJ.d[i]);
// }
for(int i=1;i<=k;i++){
scanf("%d%d",&a,&b);
if(DJ.d[a]<=b)ans++;
}
printf("%d",ans);
}
题解:
#include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; typedef long long ll; typedef pair<int,int> pii; const int MAXV=100005; const ll INF=0x3f3f3f3f3f3f3f; int n,m,k; ll dt[MAXV]; int vis[MAXV]; int p[MAXV]; vector<pii>g[MAXV]; void init() { scanf("%d%d%d",&n,&m,&k); for(int i=0;i<m;i++) { int s,t,w; scanf("%d%d%d",&s,&t,&w); g[s].push_back(make_pair(t,w)); g[t].push_back(make_pair(s,w)); } } int spfa(){ for(int i=1;i<=n;i++) dt[i]=INF; memset(p, 0, sizeof(p)); queue<int>q; dt[1]=0; vis[1]=1; q.push(1); int ans=0; for(int j=0;j<k;j++) { int s,d; scanf("%d%d",&s,&d); if(dt[s]>d) { if(dt[s]!=INF) ans++; dt[s]=d; p[s]=1; if(vis[s]==0) { vis[s]=1; q.push(s); } } else ans++; } ll v,u,x; while(!q.empty()){ v=q.front(); q.pop(); vis[v]=0; for(int i=0;i<g[v].size();i++){ u=g[v][i].first; x=g[v][i].second; if(dt[v]+x<=dt[u]&&p[u]) { p[u]=0;ans++; } if(dt[v]+x<dt[u]){ dt[u]=dt[v]+x; if(!vis[u]){ vis[u]=1; q.push(u); } } } } return ans; } int main() { init(); printf("%d\n",spfa()); return 0; }
E - Jzzhu and Apples
CodeForces - 450E
题意:一个1~n的序列,求其中最多能组成的(最大公约数>1的)数对数.
思路:从n/2的质数开始操作,统计他的倍数,倍数为偶数个则全部删去,为奇数个则保留它的2倍,其他删去.
失败的代码:
题解:
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
int n;
bool p[100010], u[100010];
vector<int> v;
set< pair<int, int> > ans;
int main() {
scanf("%d", &n);
for (int i = 2; i <= n; i++) {
if (p[i])
continue;
for (__int64 j = 1LL * i * i; j <= n; j += i)
p[j] = 1;
}
for (int i = 3; 2 * i <= n; i++) {
if (p[i])
continue;
for (int j = i; j <= n; j += i) {
if (!u[j])
v.push_back(j);
}
if (v.size() % 2)
swap(*v.rbegin(), v[1]);
for (int j = 0; j + 1 < v.size(); j += 2) {
ans.insert(make_pair(v[j], v[j + 1]));
u[v[j]] = u[v[j + 1]] = 1;
}
v.clear();
}
for (int i = 2, j = n; 1;) {
while (i < j && (u[i] || i % 2))
i++;
while (j > i && (u[j] || j % 2))
j--;
if (i >= j)
break;
ans.insert(make_pair(i++, j--));
}
printf("%d\n", ans.size());
for (set< pair<int, int> >::iterator i = ans.begin(); i != ans.end(); i++)
printf("%d %d\n", i->first, i->second);
}