A:水题,先排序,有相连的输出2,否则输出1.
#includeusing namespace std; #define pii pair #define mkp make_pair #define pb push_back #define fi first #define se second typedef long long ll; const int INF=0x3f3f3f3f; int q,n; const int maxn=110; int a[maxn]; int main() { scanf("%d",&q); while(q--) { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",a+i); sort(a+1,a+1+n); int cnt=1; for(int i=2;i<=n;++i) { if(a[i]-a[i-1]==1) {cnt=2;break;} } printf("%d\n",cnt); } return 0; }
B1和B2: 水题:同一个循环里面的步数一样,O(N)跑一遍即可。
#includeusing namespace std; #define pii pair #define mkp make_pair #define pb push_back #define fi first #define se second typedef long long ll; const int INF=0x3f3f3f3f; int q,n; const int maxn=2e5+10; int p[maxn],cnt[maxn],vis[maxn]; int main() { scanf("%d",&q); while(q--) { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",p+i),cnt[i]=vis[i]=0; for(int i=1;i<=n;++i) { if(vis[i]) continue; int ans=1,num=p[i];vis[i]=i; while(num!=i) { num=p[num]; vis[num]=i; ans++; } cnt[i]=ans; } for(int i=1;i<=n;++i) printf("%d%c",cnt[vis[i]],i==n?'\n':' '); } return 0; }
C1和C2: 水题:很显然>=n的最大的只要把n里面所有的3的幂去除,然后把剩下未选中的挑一个最小的且比去除之后的n大的加入答案就行。注意到样例里面给的最大的那个是3^38.
#includeusing namespace std; typedef long long ll; ll a[40]; void prework() { a[0]=1; for(int i=1;i<=39;++i) a[i]=a[i-1]*3; } int q; ll n,cn; int main() { prework(); scanf("%d",&q); while(q--) { scanf("%lld",&n); ll ans=0; cn=n; int flag=-1,tmp=-1,tt=0; for(int i=38;i>=0;--i) { if(n==a[i]){ans=a[i];tt=1;break;} if(a[i] 1;break;} } if(tt){printf("%lld\n",ans);continue;} for(int i=tmp-1;i>=0;--i) { if(n==a[i]){ans+=a[i];tt=1;break;} if(n>a[i]) {n-=a[i];ans+=a[i];} else flag=i; } if(tt){printf("%lld\n",ans);continue;} if(flag!=-1) { for(int i=0;i a[i]; ans+=a[flag]; } else ans=a[tmp]; printf("%lld\n",ans); } return 0; }
D1和D2:
D1可以暴力:set维护答案。
#includeusing namespace std; #define pii pair #define mkp make_pair #define pb push_back #define fi first #define se second typedef long long ll; const int INF=0x3f3f3f3f; const int maxn=210; int k,n,cnt[maxn],vis[maxn]; struct Node{ int l,r,id; }p[maxn]; bool cmp(Node &a,Node &b){return a.r<b.r;} vector v[maxn]; set<int> st; int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;++i) { scanf("%d%d",&p[i].l,&p[i].r);p[i].id=i; for(int j=p[i].l;j<=p[i].r;++j) v[j].push_back(Node{p[i].l,p[i].r,i}),cnt[j]++; } //for(int i=1;i<=200;++i) cout< for(int i=1;i<=200;++i) sort(v[i].begin(),v[i].end(),cmp); for(int i=1;i<=200;++i) { if(cnt[i]>k) { int nn=cnt[i]-k; for(int j=v[i].size()-1;j>=0&&nn;--j) { if(vis[v[i][j].id]) continue; st.insert(v[i][j].id),nn--; vis[v[i][j].id]=1; for(int k=v[i][j].l;k<=v[i][j].r;++k) cnt[k]--; } } } int len=st.size(); printf("%d\n",len); set<int>::iterator it; for(it=st.begin();it!=st.end();++it) printf("%d ",(*it)); puts(""); return 0; }
D2用线段树。按照 r 从小到大排序。然后从i 1-n枚举,如果区间最大值 最后依次输出答案; E:水题:DP即可。设f[i][0],f[i][1]表示选择楼梯和电梯的状态,直接按照题意模拟就行。 F题:暴力贪心。n<=200直接暴力找从深度为n开始距离k以内的点集和。 贪心的取比较大的值即可。 #include
#include
将所有点按照深度从大到小排序,如果当前点点权a[i]大于0,则将距离为k以内的所有点减a[i]
代表取了当前点,为答案贡献a[i]
如果下面又扫到大于零的点权,说明那个点比这个大,于是取那个#include