题目地址:https://ac.nowcoder.com/acm/contest/30532
题目难度偏简单,做出了7道快8道,认真做可能估计8-9道左右。
#include
using namespace std;
const int N=1e5+10;
int a[N],b[N],n;
int main(void)
{
cin>>n;
for(int i=0;i<n;i++) cin>>a[i],b[i]=a[i];
sort(a,a+n);
for(int i=0;i<n;i++)
{
if(b[i]==a[n-1]) cout<<b[i]+a[n-2]<<" "; //是最大值,则加倒数第二数
else cout<<b[i]+a[n-1]<<" ";
}
return 0;
}
#include
using namespace std;
typedef long long int LL;
LL n;
LL quick(LL a,LL b,LL p)
{
LL sum=1;
while(b)
{
if(b&1) sum=sum*a%p;
b>>=1;
a=a*a%p;
}
return sum%p;
}
int main(void)
{
cin>>n;
cout<<quick(n,n,n+2)<<endl;
return 0;
}
#include
using namespace std;
string a,b;
map<string,int>mp;
vector<string>ve;
int main(void)
{
getline(cin,a);
stringstream l(a);
int cnt=0;
while(l>>b)
{
cnt++;
ve.push_back(b);
if(cnt==2)//说明一个名字 一个数字了
{
mp[ve[0]]+=stoi(ve[1]);
ve.clear();
cnt=0;
}
}
int n; cin>>n;
while(n--)
{
cin>>a;
cout<<mp[a]<<endl;
}
return 0;
}
#include
using namespace std;
typedef long long int LL;
const int mod=1e9+7;
LL n,f[100],k;
vector<LL>ve;
int main(void)
{
cin>>n>>k;
for(LL i=0,j=1;i<=31;i++,j=j*k%mod) f[i]=j%mod;
LL sum=0;
for(int i=31;i>=0;i--)
if(n>>i&1) sum=(sum+f[i])%mod;
cout<<sum;
return 0;
}
#include
using namespace std;
typedef pair<int,int> PII;
typedef long long int LL;
const int N=510;
int t,n,m,k,a,b,c,d;
int s[N][N],st[N][N],dist[N][N];
int bfs(int x,int y,int w)
{
memset(st,0,sizeof st);
memset(dist,0x3f,sizeof dist);
queue<PII>q; q.push({a,b}); st[a][b]=1; dist[a][b]=0;
int dx[8]={};
while(q.size())
{
auto temp=q.front(); q.pop();
int x=temp.first,y=temp.second;
if(x==c&&y==d) return dist[x][y];
if(w==1)
{
int dx[8]={-2,-2,1,1,-1,-1,2,2};
int dy[8]={-1,1,-2,2,-2,2,-1,1};
for(int i=0;i<8;i++)
{
int tempx=x+dx[i],tempy=y+dy[i];
if(tempx<1||tempx>n||tempy<1||tempy>m) continue;
if(st[tempx][tempy]) continue;
if(s[tempx][tempy]) continue;
st[tempx][tempy]=1;
dist[tempx][tempy]=dist[x][y]+1;
q.push({tempx,tempy});
}
}else
{
int dx[8]={-2,-2,1,1,-1,-1,2,2};
int dy[8]={-1,1,-2,2,-2,2,-1,1};
int dx1[8]={-1,-1,0,0,0,0,1,1};//马脚
int dy1[8]={0,0,-1,1,-1,1,0,0};//马脚
for(int i=0;i<8;i++)
{
int tempx=x+dx[i],tempy=y+dy[i];
if(tempx<1||tempx>n||tempy<1||tempy>m) continue;
if(st[tempx][tempy]) continue;
if(s[tempx][tempy]) continue;
if(s[x+dx1[i]][y+dy1[i]]) continue;//憋马脚了
st[tempx][tempy]=1;
dist[tempx][tempy]=dist[x][y]+1;
q.push({tempx,tempy});
}
}
}
return -1;
}
int main(void)
{
cin>>t;
while(t--)
{
scanf("%d%d%d%d%d%d%d",&n,&m,&k,&a,&b,&c,&d);
memset(s,0,sizeof s);
while(k--)
{
int x,y; scanf("%d%d",&x,&y);
s[x][y]++;
}
int ans1=bfs(a,b,1);
int ans2=bfs(a,b,2);
printf("%d %d\n",ans1,ans2);
}
return 0;
}
#include
using namespace std;
typedef long long int LL;
const int N=1e6+10;
int t,n,a[N],b[N];
bool cmp(int a,int b){return a>b;}
int main(void)
{
cin>>t;
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++) scanf("%d",&b[i]);
LL sum=0;
sort(a+1,a+n+1);
sort(b+1,b+n+1,cmp);
for(int i=1;i<=n;i++) sum+=1ll*a[i]*b[i];
cout<<sum<<endl;
}
return 0;
}
很容易的分析出,它是有单调性的。即当右边界满足的时候,后面的也一定满足。
故可以双指针来维护,需要注意的是 a==0 b==0
这种情况,还需额外加1。因为题目说了可以啥都不选。
#include
using namespace std;
const int N=1e6+10;
typedef unsigned long long int LL;
LL n,a,b,s[N];
string c;
bool check(int i,int j)
{
int l=s[j]-s[i-1];
int r=(j-i+1)-l;
if(l>=b&&r>=a) return true;
return false;
}
int main(void)
{
cin>>n>>a>>b>>c;
c="*"+c;
for(int i=1;i<=n;i++) s[i]=s[i-1]+c[i]-'0';
long long int ans=0;
for(int i=1,j=1;i<=n;i++)
{
while(j<=n&&!check(i,j)) j++;
while(j<=n&&j<i) j++;
if(j<=n&&check(i,j)) ans+=(n-j+1);
}
if(!a&&!b) ans++;
cout<<ans;
return 0;
}
这道还是挺有意思的,难度就在于输出,以及字典序最小输出。
我们可以从大到小排序。这样的话它会一直的覆盖,此时最后的就是做小的字典序。
存前驱结点可以用一个数组来存。
#include
using namespace std;
const int N=3010;
int f[N],a[N],pre[N],n,m; //pre[i] 表示放到i高时的 最后一个硬币的高度
bool cmp(int a,int b){return a>b;}
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1,cmp);
for(int i=0;i<N;i++) f[i]=1e9;
f[0]=0,pre[0]=0;
for(int i=1;i<=n;i++)
{
for(int j=m;j>=a[i];j--)
{
if(f[j]>f[j-a[i]]+1 || (f[j] == f[j-a[i]]+1 && pre[j] > a[i])){
f[j] = f[j-a[i]]+1;
pre[j] = a[i];
}
}
}
if(f[m]>=1e9)
{
cout<<-1;
return 0;
}
cout<<f[m]<<endl;
vector<int>ve;
for(int i=m;i>0;i-=pre[i]) ve.push_back(pre[i]);
sort(ve.begin(),ve.end());
for(int i=0;i<ve.size();i++) cout<<ve[i]<<" ";
return 0;
}
可以很快的想到trie树,但是处理的话相对于传统的异或trie多了一步的扩展。
#include
using namespace std;
const int N=1e5*3+10;
int son[N*6][10],cnt[N*6],idx;
int n,a[N],numbre[N];
void add(int x,int c)
{
for(int i=0;i<=5;i++)
numbre[i]=x%10,x/=10;
int p=0;
for(int i=5;i>=0;i--)
{
int u=numbre[i];
if(!son[p][u]) son[p][u]=++idx;
p=son[p][u];
cnt[p]+=c;
}
}
int query(int x)
{
int sum=0;
for(int i=0;i<=5;i++)
numbre[i]=x%10,x/=10;
int p=0;
for(int i=5;i>=0;i--)
{
int maxv=0,index=0;
for(int j=0;j<=9;j++) //枚举找到最大的满足条件的
{
if(son[p][j]&&cnt[son[p][j]])
{
int temp=(numbre[i]+j)%10;
if(temp>=maxv) maxv=temp,index=j;
}
}
sum=sum*10+maxv;
p=son[p][index];
}
return sum;
}
int main(void)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],add(a[i],1);
for(int i=1;i<=n;i++)
{
add(a[i],-1);
cout<<query(a[i])<<" ";
add(a[i],1);
}
return 0;
}
#include
using namespace std;
const int N=1e6*2+10;
typedef long long int LL;
typedef pair<LL,LL> PII;
int h[N],e[N],w[N],ne[N],idx;
LL dist[N];
int st[N],n,m;
void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void spfa()
{
for(int i=1;i<=n;i++) dist[i]=1e18;
dist[1]=0;
priority_queue<PII,vector<PII>,greater<PII>>q; q.push({0,1});
while(q.size())
{
auto temp=q.top(); q.pop();
int u=temp.second;
if(st[u]) continue;
st[u]=1;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(dist[j]>dist[u]+w[i])
{
dist[j]=dist[u]+w[i];
q.push({dist[j],j});
}
}
}
}
int main(void)
{
memset(h,-1,sizeof h);
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int a,b,c; scanf("%d%d%d",&a,&b,&c);
add(a,b,c),add(b,a,c);
}
int t; cin>>t;
spfa();
while(t--)
{
int a,b; scanf("%d%d",&a,&b);
printf("%lld\n",dist[a]+dist[b]);
}
return 0;
}
#include
using namespace std;
vector<double>ve;
int n;
int main(void)
{
cin>>n;
ve.push_back(0),ve.push_back(10);
for(int i=0;i<n;i++)
{
string op; cin>>op;
if(op=="C")
{
double x; cin>>x;
ve.push_back(x);
sort(ve.begin(),ve.end());
}else
{
double x; cin>>x;
if(x==10) printf("%.5lf\n",10-ve[ve.size()-2]);//最后一个位置
else
{
int index=upper_bound(ve.begin(),ve.end(),x)-ve.begin();
printf("%.5lf\n",ve[index]-ve[index-1]);
}
}
}
return 0;
}
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 500010;
struct Node
{
int l, r;
LL sum, d;
}tr[N * 4];
LL tr1[N],tr2[N];
LL w[N];
int n,m;
LL gcd(LL a, LL b) {return b ? gcd(b, a % b) : a;}
void pushup(Node &u,Node &l,Node &r)
{
u.sum=l.sum+r.sum;
u.d=gcd(l.d,r.d);
}
void pushup(int u)
{
pushup(tr[u],tr[u<<1],tr[u<<1|1]);
}
void build(int u,int l,int r)
{
if(l==r)
{
LL d=w[r]-w[r-1];
tr[u]={l,r,d,d};
}
else
{
tr[u]={l,r};
int mid=l+r>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
pushup(u);
}
}
Node query(int u,int l,int r)
{
if(tr[u].l>=l&&tr[u].r<=r) return tr[u];
else
{
int mid=tr[u].l+tr[u].r>>1;
if(r<=mid) return query(u<<1,l,r);
else if(l>mid) return query(u<<1|1,l,r);
else
{
auto left=query(u<<1,l,r);
auto right=query(u<<1|1,l,r);
Node res;
pushup(res,left,right);
return res;
}
}
}
void modify(int u,int x, LL v)
{
if(tr[u].l==x&&tr[u].r==x)
{
LL b=tr[u].sum+v;
tr[u]={x,x,b,b};
}
else
{
int mid=tr[u].l+tr[u].r>>1;
if(x<=mid) modify(u<<1,x,v);
else modify(u<<1|1,x,v);
pushup(u);
}
}
int lowbit(int x)
{
return x&-x;
}
void add(LL tr[],int x,LL c)
{
for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c;
}
LL sum(LL tr[],int x)
{
LL res=0;
for(int i=x;i;i-=lowbit(i)) res+=tr[i];
return res;
}
LL get(int x)
{
return sum(tr1,x)*(x+1)-sum(tr2,x);
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>w[i];
build(1,1,n);
for(int i=1;i<=n;i++)
{
int d=w[i]-w[i-1];
add(tr1,i,d),add(tr2,i,(LL)i*d);
}
while (m -- )
{
int op;
int l,r;
cin>>op>>l>>r;
if(l>r) swap(l,r);
if(op==2)
{
auto left=query(1,1,l);
Node right={0,0,0,0};
if(l+1<=r) right=query(1,l+1,r);
printf("%lld\n",abs(gcd(left.sum,right.d)));
}
else if(op==0)
{
LL d;
cin>>d;
add(tr1,l,d),add(tr1,r+1,-d);
add(tr2,l,l*d),add(tr2,r+1,(r+1)*-d);
modify(1,l,d);
if(r+1<=n) modify(1,r+1,-d);
}
else
{
printf("%lld\n",get(r)-get(l-1));
}
}
return 0;
}