Chocolate Bunny (交互)

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

This is an interactive problem.

We hid from you a permutation pp of length nn, consisting of the elements from 11 to nn. You want to guess it. To do that, you can give us 2 different indices ii and jj, and we will reply with pimodpjpimodpj (remainder of division pipi by pjpj).

We have enough patience to answer at most 2⋅n2⋅n queries, so you should fit in this constraint. Can you do it?

As a reminder, a permutation of length nn is an array consisting of nn distinct integers from 11 to nn in arbitrary order. For example, [2,3,1,5,4][2,3,1,5,4] is a permutation, but [1,2,2][1,2,2] is not a permutation (22 appears twice in the array) and [1,3,4][1,3,4] is also not a permutation (n=3n=3 but there is 44 in the array).

Input

The only line of the input contains a single integer nn (1≤n≤1041≤n≤104) — length of the permutation.

Interaction

The interaction starts with reading nn.

Then you are allowed to make at most 2⋅n2⋅n queries in the following way:

  • "? x y" (1≤x,y≤n,x≠y1≤x,y≤n,x≠y).

After each one, you should read an integer kk, that equals pxmodpypxmodpy.

When you have guessed the permutation, print a single line "! " (without quotes), followed by array pp and quit.

After printing a query do not forget to output end of line and flush the output. Otherwise, you will get Idleness limit exceeded. To do this, use:

  • fflush(stdout) or cout.flush() in C++;
  • System.out.flush() in Java;
  • flush(output) in Pascal;
  • stdout.flush() in Python;
  • see documentation for other languages.

Exit immediately after receiving "-1" and you will see Wrong answer verdict. Otherwise you can get an arbitrary verdict because your solution will continue to read from a closed stream.

Hack format

In the first line output nn (1≤n≤1041≤n≤104). In the second line print the permutation of nn integers p1,p2,…,pnp1,p2,…,pn.

Example

input

3

1

2

1

0

output

? 1 2

? 3 2

? 1 3

? 2 1

! 1 3 2

题意:

       经过2*n次询问,找到一个为1到n的序列p。每次提问格式为:? x y。每次提问可以得到一个余数,如 ? 1 2,可以得到一个p[1] % p[2] 的值。

       解题核心思路是:

       经过两次提问一定可以得到一个序列内的数:

       设x,y两个数,且x > y。

  • ? x y: mod1 = x % y
  • ? y x: mod2 = y % x

       因为y < x,则mod2 <= y,mod1 又是% y所得,所以mod1 < y。

       因此每两次询问,一定可以得到一下结论之一:

  • mod1 > mod2 = x
  • mod2 > mod1 = y

       若序列为 1 3 2,即p[1] = 1,p[2] = 3,p[3] = 2。

  • ? 1 2:  mod1 = p[1] % p[2] = 1;
  • ? 2 1:  mod2 = p[2] % p[1] = 0;

       其中mod1 > mod2 = p[1] = 1,其他以此类推。

    

#include<bits/stdc++.h>
using namespace std;

const int N = 1e4 + 5;
int a[N]; 
int q[N<<1], hh, tt = -1;
int main() {
	int n; cin>>n;
	for(int i = 1 ;i <= n; ++i)
		q[++tt] = i;
	int sum = n * (n+1) / 2;

	//由于一次是取两个,再存一个没有被选出的数。
	// 因此队列每次减少2个。当队列只有一个数的时候不能进行以下操作 
	while(hh < tt) {
		int x = q[hh++];
		int y = q[hh++];
		cout<<"? "<<x<<" "<<y<<endl;
		cout<<"? "<<y<<" "<<x<<endl;
		int mod1, mod2; cin>>mod1>>mod2;
		if(mod1 < mod2) {
			q[++tt] = x;// 将没有被选出来的数加入队列。 
			a[y] = mod2;
			sum -= mod2;
		}
		else {
			q[++tt] = y;// 将没有被选出来的数加入队列。 
			a[x] = mod1;
			sum -= mod1;
		}
	}
	a[q[hh]] = sum;
	
	cout<<"!";
	for(int i = 1; i <= n; ++i)
		cout<<" "<<a[i];
	cout<<endl;
	cout.flush();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值