eg:能做出一道交互題還是很高興的,打的是VP,過了四題之後就沒有看E題了。
傳送門
A. Kuroni and the Gifts
題意:給出兩個數組,問如何分配使得這兩個數字中對應的和相加不等。
題解:兩個數組分別從小到大排序就完事了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
ll read(){
ll f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
int n;
struct arr{
int val,no;
}a[maxn],b[maxn];
bool cmp(arr a,arr b){
return a.val<b.val;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i].val),a[i].no=i;
for(int i=1;i<=n;i++)scanf("%d",&b[i].val),b[i].no=i;
sort(a+1,a+1+n,cmp);
sort(b+1,b+1+n,cmp);
for(int i=1;i<n;i++)printf("%d ",a[i].val);
printf("%d\n",a[n].val);
for(int i=1;i<n;i++)printf("%d ",b[i].val);
printf("%d\n",b[n].val);
}
return 0;
}
B. Kuroni and Simple Strings
題意:給出一個括號串,每次可以刪除一個子序列,這個子序列的定義是((()))這種簡單括號序列。
題解:模擬題意即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
ll read(){
ll f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
char s[maxn];
int vis[1100];
int ans,cnt[1100],f[1100][1100];
int main(){
scanf("%s",s);
int len=strlen(s),l=0,r=len-1,ans=0;
while(true){
int bj=1;ans++;
for(int l=0,r=len-1;l<len && l<r;l++){
if(vis[l])continue;
if(s[l]=='('){
int flag=1;
while(r>l){
if(!vis[r] && s[r]==')'){
flag=0;bj=0;
f[ans][++cnt[ans]]=l+1;
f[ans][++cnt[ans]]=r+1;
vis[l]=1,vis[r]=1;
break;
}
r--;
}
if(flag)break;
}
}
if(bj)break;
}
ans--;
printf("%d\n",ans);
for(int i=1;i<=ans;i++){
printf("%d\n",cnt[i]);
sort(f[i]+1,f[i]+1+cnt[i]);
for(int j=1;j<cnt[i];j++)
printf("%d ",f[i][j]);
printf("%d\n",f[i][cnt[i]]);
}
return 0;
}
C. Kuroni and Impossible Calculation
題意:計算一個公式的值a數組共有n個數,每次需要對m取模。
題解:m是1000 n是2e5,抽屜原理可知如果n大於m,就必然存在一個數是m的倍數,答案肯定是0。對於n小於m平方暴力即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
ll read(){
ll f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
int n,m;
int a[maxn];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
if(n>m)puts("0");
else{
ll ans=1;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
ans=ans*1ll*abs(a[j]-a[i])%m;
printf("%lld\n",ans);
}
return 0;
}
D. Kuroni and the Celebration
題意:給出一棵樹,每次你會給出一個詢問? u v,他會返回給你lca(u,v)的值,在不超過n/2次詢問的前提下,問出這棵樹的根是誰。
題解:第一次做交互題,好緊張。這題目本身不難,只需要考慮這棵樹上入度爲1的點就行,每次做出詢問,如果lca是兩個點職中的某個點那麼顯然根就是那個點;如果不是,說明這兩個點都是葉子節點,刪除之後再push新點即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e9+7;
const int INF=0x3f3f3f3f;
ll read(){
ll f=1,x=0;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9');
do{x=x*10+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9');
return f*x;
}
int n;
vector<int>G[maxn];
int d[maxn];
queue<int>q;
void cln(int u){
for(int i=0;i<G[u].size();i++){
int x=G[u][i];
d[x]--;
if(d[x]==1)q.push(x);
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
d[u]++,d[v]++;
}
for(int i=1;i<=n;i++)
if(d[i]==1)q.push(i);
int sz=q.size();
while(sz>1){
int u=q.front();q.pop();
int v=q.front();q.pop();
cout<<"? "<<u<<" "<<v<<endl;cout.flush();
int ans;cin>>ans;
if(ans==u || ans==v){
cout<<"! "<<ans<<endl;cout.flush();
break;
}
cln(u);cln(v);
sz=q.size();
}
sz=q.size();
if(sz==1)printf("! %d\n",q.front());cout.flush();
return 0;
}