题目质量很好,尤其是F题,收获很多。
1.签到:https://ac.nowcoder.com/acm/contest/81126/A
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int x;
int main()
{
cin>>x;
cout<<8*x;
}
2.模拟:https://ac.nowcoder.com/acm/contest/81126/B
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,h;
string a[5];
int b[2];
int main()
{
cin>>n>>h;
for(int i=1;i<=5;i++) cin>>a[i-1];
for(int i=0;i<=n-1;i++)
{
if(a[0][i]=='*'&&a[1][i]=='*') b[0]++;
else if(a[0][i]=='*') b[1]++;
else continue;
}
for(int i=0;i<=n-1;i++) b[0]+=(a[1][i]=='*');
for(int i=0;i<=n-1;i++) b[0]+=(a[3][i]=='*');
for(int i=0;i<=n-1;i++)
{
if(a[4][i]=='*'&&a[3][i]=='*') b[0]++;
else if(a[4][i]=='*') b[1]++;
else continue;
}
if(h<=b[0]) cout<<h;
else{
cout<<b[0]+min(b[1],(h-b[0])/2);
}
}
3.模拟:https://ac.nowcoder.com/acm/contest/81126/C
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
int n,a[100010],x;
long long ans1[100000];
bool cmp(int a,int b)
{
return a>b;
}
long long ans=0;
int calc(int w,int cnt)
{
if(w<x) return -1;
if(w==x)
{
return cnt;
}
return calc((w+2)/3,cnt+1);
}
int qpow(int a,int b)
{
int res=1;
while(b)
{
if(b&1) res=res*a;
a=a*a;
b>>=1;
}
return res;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
cin>>x;
sort(a+1,a+n+1,cmp);
for(int i=1;i<=n;i++)
{
if(a[i]<x) break;
int w=calc(a[i],0);
if(w==-1) continue;
ans1[w]+=qpow(2,w);
}
for(int i=0;i<=100;i++) ans=max(ans,ans1[i]);
cout<<ans;
}
4.数学:https://ac.nowcoder.com/acm/contest/81126/D
把式子拆开来就可以了,下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n;
ll a[N];
int main(){
cin>>n;
for(int i=1;i<=n;++i){
cin>>a[i];
}
ll x=0,y=0,z=0;
for(ll i=1;i<=n;++i){
x+=a[i];
y+=2*i*a[i];
z+=i*i*a[i];
}
ll ans=0x3f3f3f3f3f3f3f3f;
for(ll i=1;i<=n;++i){
ans=min(ans,i*i*x-i*y+z);
}
cout<<ans<<endl;
}
5.DP:https://ac.nowcoder.com/acm/contest/81126/E
我们令dp[i][j][k]表示用前i个煤炭烧j个铁矿石用k次魔法的最短时间,接下来就是比较常规的转移,这里注意下vector来代替数组。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,x,y;
int main()
{
cin>>n>>m;
vector<long long> x(n+5),y(n+5);
vector<vector<vector<long long> > > dp(n+1,vector<vector<long long>>(m+1,vector<long long>(2,1e16)));
dp[0][0][0]=dp[0][0][1]=0;
for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
for(int i=1;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
dp[i][j][0]=dp[i-1][j][0];
dp[i][j][1]=dp[i-1][j][1];
dp[i][j][0]=min(dp[i][j][0],dp[i-1][max((ll)0,j-x[i])][0]+y[i]);
dp[i][j][1]=min(dp[i][j][1],dp[i-1][max(0ll,j-x[i])][1]+y[i]);
dp[i][j][1]=min(dp[i][j][1],dp[i-1][max(0ll,j-2*x[i])][0]+y[i]/2);
}
}
cout<<min(dp[n][m][0],dp[n][m][1]);
}
注意这里的1e16就是为其赋初值的。
6.差分:https://ac.nowcoder.com/acm/contest/81126/F

这里还有一个比较秒的点就是用map<int,vector<int>>实现了在多条用重叠的边的差分操作。
下面是AC代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,w[100010],v[100010],x[100010];
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>w[i];
w[i]+=w[i-1];
}
for(int i=1;i<=n;i++) cin>>v[i];
for(int i=1;i<=m;i++) cin>>x[i];
map<int,vector<int> > mp;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
mp[w[i-1]+1-x[j]].push_back(v[i]);
mp[w[i]+1-x[j]].push_back(-v[i]);
}
}
int now=0;
set<int> st;
st.insert(0);
for(auto [k,v]:mp)
{
for(auto dd:v)
{
now+=dd;
}
st.insert(now);
}
cout<<st.size();
}
NowcoderACM比赛中的C++编程挑战与解题策略
1120

被折叠的 条评论
为什么被折叠?



