B - Friends and Cookies
找规律,除了第一项以外 ,发现它是2*(n-1)项一循环,根据规律进行处理。因为把–写成++,错交好多发,吐血。。。
#include<iostream>
#define ll unsigned long long
using namespace std;
ll a[10005];
int main()
{
std::ios::sync_with_stdio(false);
ll x, n;
ll p1, p2, p3;
int t;
cin >> t;
while (t--)
{
cin >> x >> n;
if(n==1)
{
cout<<x<<endl;
continue;
}
p1 = (x - 1) / (n - 1);
p2 = (x - 1) % (n - 1);
a[1] = p1 + 1;
for (int i = 2; i <= n; i++)
{
a[i] = p1;
}
if (p1 % 2 == 1)
{
int temp = n - 1;
a[1]-=((p1-1)/2);
a[n]-=((p1-1)/2);
a[1]--;
while (p2 > 0)
{
a[temp--]++;
p2--;
}
}
else
{
int temp = 2;
a[1]-=(p1/2);
a[n]-=(p1/2);
while (p2 > 0)
{
a[temp++]++;
p2--;
}
}
for (int i = 1; i < n; i++)
cout << a[i] << " ";
cout << a[n] << endl;
}
return 0;
}
C-Flip the Bits
水题,读不懂题就很坑
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int t,ans,n,N;
cin>>t;
while(t--)
{
cin>>n;
N=n;
ans=1;
while(n>0)
{
if(n&1)
break;
ans++;
n/=2;
}
cout<<ans<<endl;
}
return 0;
}
* D-Magic Sticks*
找规律。注意要用long long
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
int main()
{
int t;
ll n,m,ans1,ans2;
cin>>t;
while(t--)
{
cin>>n>>m;
if(n%2==1)
{
if(m%2==1)
{
n++;
ans1=n/2*(m/2+m/2+1);
n--;
}
else
{
n++;
ans1=m/2*n;
n--;
}
}
else
{
if(m%2==1)
{
ans1=n/2*(m/2+1)+(n/2+1)*(m/2);
}
else
{
ans1=(n+1)*m/2;
}
}
swap(m,n);
if(n%2==1)
{
if(m%2==1)
{
n++;
ans2=n/2*(m/2+m/2+1);
n--;
}
else
{
n++;
ans2=m/2*n;
n--;
}
}
else
{
if(m%2==1)
{
ans2=n/2*(m/2+1)+(n/2+1)*(m/2);
}
else
{
ans2=(n+1)*m/2;
}
}
cout<<min(ans1,ans2)<<endl;
}
return 0;
}
E- N-Dimensional Grid
一开始把计算方法找错了,后来才发现是用升维的思路做的。
#include<iostream>
#include<cstdio>
#define mod 1000000007
using namespace std;
long long a[100005];
long long b[100005];
long long ans;
int main()
{
//std::ios::sync_with_stdio(false);
int t,n;
long long m,ans;
//cin>>t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
m=1;
ans=0;
for(int i=0;i<n;i++)
{
scanf("%lld",&a[i]);
if(i==0)
b[i]=a[i]-1;
else
{
b[i]=(b[i-1]*a[i]%mod+m*(a[i]-1)%mod)%mod;
}
m*=a[i];
m=m%mod;
}
printf("%lld\n",b[n-1]);
//cout<<ans<<endl;
}
return 0;
}
* F-Minimum Sum of Array*
用一个数组记录每个数字出现的次数。从最小值到最大值遍历一遍,遍历的过程中将该数的倍数出现的次数全部加到该数的次数上,将倍数的次数置零。每遍历一个数,就将结果加等于该数乘出现的次数。比之前想的每次二分查找再一一修改要快很多。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<memory.h>
using namespace std;
long long a[1000005];
//int v[1000005];
int main()
{
std::ios::sync_with_stdio(false);
int t,n,temp;
long long ans,maxn,minl,x;
cin>>t;
while(t--)
{
cin>>n;
ans=0;
maxn=0;
minl=1e9;
memset(a,0,sizeof(a));
for(int i=0;i<n;i++)
{
cin>>x;
a[x]++;
maxn=max(maxn,x);
minl=min(minl,x);
}
for(long long i=minl;i<=maxn;i++)
{
if(a[i]==0)
continue;
for(long long j=2*i;j<=maxn;j+=i)
{
if(a[j]!=0)
{
a[i]+=a[j];
a[j]=0;
}
}
ans+=a[i]*i;
}
cout<<ans<<endl;
}
return 0;
}
H - Making Friends
#include<iostream>
#include<algorithm>
using namespace std;
int a[2005];
int main()
{
int t,n,ans;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=2*n;i++)
cin>>a[i];
ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,a[i]+a[2*n-i+1]);
cout<<ans<<endl;
}
return 0;
}
I - Split the Number
注意-1的情况
#include<iostream>
using namespace std;
int a[1005];
int main()
{
int t,x,n,cnt,ans,p;
cin>>t;
while(t--)
{
cin>>x>>n;
if(x<n)
{
cout<<-1<<endl;
continue;
}
ans=x/n;
p=x%n;
for(int i=n;i>1;i--)
{
if(i<=p)
cout<<ans+1<<" ";
else
cout<<ans<<" ";
}
if(p!=0)
cout<<ans+1<<endl;
else
cout<<ans<<endl;
}
return 0;
}
M - Greedy Pirate
找lca,画图分析。参照网上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<memory.h>
#define maxn 100005
using namespace std;
int head[maxn],to[maxn*4],next[maxn*4],v[maxn*4];
int tot;
int up[maxn],down[maxn];//down以该节点为终点,up为以该节点为起点
int fa[maxn];
int deep[maxn];
int p[maxn][30];
void add(int a,int b,int c1,int c2)
{
to[++tot]=b;
v[tot]=c1;
next[tot]=head[a];
head[a]=tot;
to[++tot]=a;
v[tot]=c2;
next[tot]=head[b];
head[b]=tot;
}
void dfs(int p,int f,int t)
{
fa[p]=f;
deep[p]=t;
for(int i=head[p];i!=-1;i=next[i])
{
int b=to[i];
if(b==f)
up[p]=up[f]+v[i];
}
for(int i=head[p];i!=-1;i=next[i])
{
int b=to[i];
if(b==f)
continue;
down[b]=down[p]+v[i];//一个节点向上的路径是惟一的,所以记录根到该节点的路径,而不是记录该节点到叶子的路径
dfs(b,p,t+1);
}
}
void init(int n)
{
memset(p,-1,sizeof(p));
for(int i=1;i<=n;i++)
{
p[i][0]=fa[i];
}
for(int i=1;;i++)
{
int pre=1;
for(int j=1;j<=n;j++)
{
if(p[j][i-1]!=-1)
{
pre=0;
p[j][i]=p[p[j][i-1]][i-1];
}
}
if(pre)
break;
}
}
int lca(int a,int b)
{
if(deep[a]>deep[b])
swap(a,b);
int i;
for(i=0;(1<<i)<deep[b];i++);
i--;
for(;;)
{
if(deep[a]==deep[b])
break;
if(deep[b]-deep[a]<(1<<i))
i--;
else
b=p[b][i];
}
for(i=0;(1<<i)<deep[b];i++);
i--;
for(;;){
if(a==b)
return a;
if(fa[a]==fa[b])
return fa[a];
if(p[a][i]==p[b][i])
i--;
else a=p[a][i],b=p[b][i];
}
}
int main()
{
int t,sum,q,n;
int a,b,c1,c2;
cin>>t;
while(t--)
{
cin>>n;
memset(head,-1,sizeof(head));
tot=0;
sum=0;
for(int i=1;i<n;i++)
{
//cin>>a>>b>>c1>>c2;
scanf("%d%d%d%d",&a,&b,&c1,&c2);
add(a,b,c1,c2);
sum+=(c1+c2);
}
up[1]=down[1]=0;
dfs(1,-1,1);
init(n);
cin>>q;
while(q--)
{
//cin>>a>>b;
scanf("%d%d",&a,&b);
int f=lca(a,b);
//cout<<sum-(up[b]+down[a]-up[f]-down[f])<<endl;
printf("%d\n",sum-(up[b]+down[a]-up[f]-down[f]));
}
}
return 0;
}