zsy:

Guess the Array
Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u
Submit

Status

Practice

CodeForces 727C
Description
This is an interactive problem. You should use flush operation after each printed line. For example, in C++ you should use fflush(stdout), in Java you should use System.out.flush(), and in Pascal — flush(output).

In this problem you should guess an array a which is unknown for you. The only information you have initially is the length n of the array a.

The only allowed action is to ask the sum of two elements by their indices. Formally, you can print two indices i and j (the indices should be distinct). Then your program should read the response: the single integer equals to ai + aj.

It is easy to prove that it is always possible to guess the array using at most n requests.

Write a program that will guess the array a by making at most n requests.

Sample Input
Input
5

9

7

9

11

6

Output

? 1 5

? 2 3

? 4 1

? 5 2

? 3 4

! 4 6 1 5 5
Hint
The format of a test to make a hack is:

The first line contains an integer number n (3 ≤ n ≤ 5000) — the length of the array.
The second line contains n numbers a1, a2, …, an (1 ≤ ai ≤ 105) — the elements of the array to guess.

题意:根据提示算出一个长度已知的数列。规则:给出长度n。输出? x y获取x+y,只能问n次。数列长度>=3
思路:首先确定数列前三个数(a,b,c):获取a+b;a+c;b+c。通过解方程组可以确定a,b,c;
之后第四个数,可以通过获取第三加第四个数的和来确定;以此类推。

AC代码:

//#define LOCAL
#include <stdio.h>
#include <stdlib.h>

int main(){
    int *a,n;
    int b[3];
    int i;
    #ifdef LOCAL
    freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    #endif
    scanf("%d",&n);
    a=(int*)malloc(sizeof(int)*n);  //由于数据量未知,因此用动态内存分配 
    printf("\n? 1 2\n");
    fflush(stdout);     //题目中要求在每个printf后加此代码 
    scanf("%d",&b[0]);
    printf("\n? 1 3\n");
    fflush(stdout);
    scanf("%d",&b[1]);
    printf("\n? 2 3\n");
    fflush(stdout);
    scanf("%d",&b[2]);
    a[0]=(b[0]+b[1]-b[2])/2;
    a[1]=(b[0]-b[1]+b[2])/2;
    a[2]=(-b[0]+b[1]+b[2])/2;
    for(i=3;i<n;i++){
        int s;
        printf("\n? %d %d\n",i,i+1);
        fflush(stdout);
        scanf("%d",&s);
        a[i]=s-a[i-1];
    }
    printf("\n");
    printf("! ");
    for(i=0;i<n;i++){
        printf("%d",a[i]);
        fflush(stdout);
        if(i<n-1) printf(" ");
        fflush(stdout);
    }
    free(a);    //释放内存 
    return 0;
}