题意:每个盒子可以分成k部分,共有b块挡板,a个nuts,每部分最多可以放v个,最少需要多少个盒子
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
//freopen("in.txt","r",stdin);
int k,a,b,v,sum=0;
cin>>k>>a>>b>>v;
while(true)
{
if(a<=0)break;
if(b<k-1)
{
a-=(b+1)*v;
sum++;
if(a>0)
sum+=(a%v==0)?a/v:(a/v+1);
b=0;
break;
}
int cnt=b/(k-1);
if(cnt*k*v<=a)
{
sum+=cnt;
a-=cnt*k*v;
b-=cnt*(k-1);
}
else
{
int m=a/(k*v);
sum+=m;
if(a%(k*v))sum++;
a=0;
}
}
cout<<sum<<endl;
return 0;
}
B - Trees in a Row
题意:给一个序列要求a(i+1)-ai=k,问最少需要修改多少个数
思路:枚举每个数,找到最小修改值
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1010;
const int INF=1000000000;
int n,k,a[maxn];
void Print(int mid)
{
int x=a[mid];
for(int i=mid-1;i>=1;i--)
{
if(x-a[i]>k)cout<<"+ "<<i<<" "<<x-k-a[i]<<endl;
if(x-a[i]<k)cout<<"- "<<i<<" "<<a[i]-x+k<<endl;
x-=k;
}
x=a[mid];
for(int i=mid+1;i<=n;i++)
{
if(a[i]-x>k)cout<<"- "<<i<<" "<<a[i]-x-k<<endl;
if(a[i]-x<k)cout<<"+ "<<i<<" "<<x+k-a[i]<<endl;
x+=k;
}
}
int main()
{
//freopen("in.txt","r",stdin);
cin>>n>>k;
for(int i=1;i<=n;i++)
cin>>a[i];
int ans1=0,ans2=INF,x,ans,cnt;
bool flag;
for(int i=1;i<=n;i++)
{
int mid=i;
x=a[mid],ans1=0;
flag=true;
for(int j=mid+1;j<=n;j++)
{
if(a[j]-x!=k)ans1++;
x=x+k;
}
x=a[mid];
for(int j=mid-1;j>=1;j--)
{
if(x-a[j]!=k)ans1++;
x=x-k;
if(x<=0){flag=false;break;}
}
if(!flag)continue;
if(ans1<ans2)ans2=ans1,ans=mid;
}
cout<<ans2<<endl;
Print(ans);
return 0;
}
C - Searching for Graph不知道怎么就过了。。。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int t,n,p;
cin>>t;
while(t--)
{
cin>>n>>p;
int sum=0;
bool flag=true;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(sum>=2*n+p){flag=false;break;}
cout<<i<<" "<<j<<endl;
sum++;
}
if(!flag)break;
}
}
return 0;
}
问你矩阵的任意次方之后,会不会出现矩阵上的所有的数字都大于0.
思路:一个矩阵a[i][j]>0,代表ij之间可走。 那么本题就化身为给定一个图,问,任意两点之间是否可达。
那么本题就化身为给定一个图,然后tarjan算法求缩点,看最后是否会缩成一个点。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
const int maxn=2020;
int n,a[maxn][maxn];
vector<int> G[maxn];
stack<int> S;
int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
void init()
{
dfs_clock=scc_cnt=0;
memset(sccno,0,sizeof(sccno));
memset(pre,0,sizeof(pre));
}
void add_edge(int x,int y)
{
G[x].push_back(y);
}
void dfs(int u)
{
pre[u]=lowlink[u]=++dfs_clock;
S.push(u);
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(!pre[v])
{
dfs(v);
lowlink[u]=min(lowlink[v],lowlink[u]);
}
else if(!sccno[v])lowlink[u]=min(lowlink[u],pre[v]);
}
if(lowlink[u]==pre[u])
{
scc_cnt++;
while(true)
{
int x=S.top();S.pop();
sccno[x]=scc_cnt;
if(x==u)break;
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d",&n);
int x;
init();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&x);
if(x)add_edge(i,j);
}
for(int i=1;i<=n;i++)
if(!pre[i])dfs(i);
if(scc_cnt>1)printf("NO\n");
else printf("YES\n");
return 0;
}