天天看点

【German Collegiate Programming Contest 2018 June 16th】 GCPC 2018 训练题 题解

Problem B: Battle Royale

Battle Royale games are the current trend in video games and Gamers Concealed Punching

Circles (GCPC) is the most popular game of them all. The game takes place in an area that, for

the sake of simplicity, can be thought of as a two-dimensional plane. Movement and positioning

are a substantial part of the gameplay, but getting to a desired location can be dangerous. You

are confident in your ability to handle the other players, however, while you are walking to your

destination, there are two hazards posed by the game itself:

• The game zone is bounded by a blue circle. Outside of this circle, there is a deadly force

field that would instantly take you out of the game.

• Inside the game zone, there is a red circle where you are exposed to artillery strikes. This

circle is also too risky to enter.

You want to move from one spot on the map to another, but the direct path to your destination is

blocked by the red circle, so you need to find a way around it. Can you find the shortest path that

avoids all hazards by never leaving the blue or entering the red circle? Touching the boundaries

of the circles is fine, as long as you do not cross them.

Input

The input consists of:

• one line with two integers xc, yc specifying your current location;

• one line with two integers xd, yd specifying your destination;

• one line with three integers xb, yb, rb specifying the center and radius of the blue circle;

• one line with three integers xr, yr, rr specifying the center and radius of the red circle.

All coordinates have an absolute value of at most 1 000, and 1 ≤ rb, rr ≤ 1 000. The red circle

is strictly inside the blue circle. Your current location and destination are strictly inside the blue

circle and strictly outside of the red circle, and the direct path between them is blocked by the

red circle.

Output

Output the length of the shortest path that does not leave the blue or enter the red circle. The

output must be accurate up to a relative or absolute error (whichever is lower) of 10−7

.

Sample Input 1 Sample Output 1

0 0

10 0

0 0 1000

5 0 2

10.8112187742

GCPC 2018 – Problem B: Battle Royale

题意:两点之间有一个圆形区域不能经过,求两点间最短距离

思路:

分别做两点到圆的切线,加上一段圆弧路径即是最短路。注意精度即可

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
using namespace std;
#define ll long long
#define maxn 0x3f3f3f3f
int read()
{
    int sign=1,ans=0;
    char ch;
    ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            sign=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        ans=(ans<<1)+(ans<<3)+(ch^48);
        ch=getchar();
    }
    return ans*sign;
}
ll n,m;
int main()
{
    double  xc,yc,xd,yd,xb,yb,rb,xr,yr,rr;
    cin>>xc>>yc>>xd>>yd>>xb>>yb>>rb>>xr>>yr>>rr;
    double K=(fabs((yd-yc)*xr+(xc-xd)*yr+((xd*yc)-(xc*yd))))/(sqrt(pow(yd-yc,2)+pow(xc-xd,2)));
        double S1=sqrt((xc-xr)*(xc-xr)+(yc-yr)*(yc-yr)),S2=sqrt((xd-xr)*(xd-xr)+(yd-yr)*(yd-yr));
        double L1=sqrt(S1*S1-rr*rr),L2=sqrt(S2*S2-rr*rr);
        double a=acos(K/S1)+acos(K/S2)-acos(rr*1.0/S1)-acos(rr*1.0/S2);
        double ans=L1+L2+a*rr;
        printf("%.10lf",ans);
    return 0;
}
           

Problem C: Coolest Ski Route

John loves winter. Every skiing season he goes heli-skiing with his friends. To do so, they rent

a helicopter that flies them directly to any mountain in the Alps. From there they follow the

picturesque slopes through the untouched snow.

Of course they want to ski on only the best snow, in the best weather they can get. For this they

use a combined condition measure and for any given day, they rate all the available slopes.

Can you help them find the most awesome route?

Input

The input consists of:

• one line with two integers n (2 ≤ n ≤ 1000) and m (1 ≤ m ≤ 5000), where n is the

number of (1-indexed) connecting points between slopes and m is the number of slopes.

• m lines, each with three integers s, t, c (1 ≤ s, t ≤ n, 1 ≤ c ≤ 100) representing a slope

from point s to point t with condition measure c.

Points without incoming slopes are mountain tops with beautiful scenery, points without outgoing

slopes are valleys. The helicopter can land on every connecting point, so the friends can start

and end their tour at any point they want. All slopes go downhill, so regardless of where they

start, they cannot reach the same point again after taking any of the slopes.

Output

Output a single number n that is the maximum sum of condition measures along a path that the

friends could take.

Sample visualization

Mt. Awesome (1)

Hunter’s Outpost (2)

Stardew Valley (3)

Canopy Vista (4)

Hungry Bear Cave (5)

Riverside Inn (6)

Figure C.1: Map of the second sample case

GCPC 2018 – Problem C: Coolest Ski Route 5

Sample Input 1 Sample Output 1

5 5

1 2 15

2 3 12

1 4 17

4 2 11

5 4 9

40

Sample Input 2 Sample Output 2

6 6

1 2 2

4 5 2

2 3 3

1 3 2

5 6 2

1 2 4

7

GCPC 2018 – Problem C: Coolest Ski Route

题意:求图中最长路径

思路:队友A的,跑一遍dfs即可。

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define ll long long
#define maxn 0x3f3f3f3f
int read()
{
    int sign=1,ans=0;
    char ch;
    ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            sign=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        ans=(ans<<1)+(ans<<3)+(ch^48);
        ch=getchar();
    }
    return ans*sign;
}
int n,m;
int a[10005];
int map1[1005][1005];
bool vis[1005];
int maxx=0;
int in[1005];
int dp[1005];
int DFS(int x)
{
    if(vis[x])
    {
        maxx=max(dp[x],maxx);
        return dp[x];
    }
    vis[x]=1;
    for(int i=1; i<=n; i++)
    {
        if(map1[x][i]!=-1)
            dp[x]=max(dp[x],DFS(i)+map1[x][i]);
    }
    maxx=max(dp[x],maxx);
    return dp[x];
}
int main()
{
    n=read();
    m=read();
    memset(map1,-1,sizeof(map1));
    for(int i=0; i<m; i++)
    {
        int x,y,z;
        x=read();
        y=read();
        z=read();
        in[y]++;
        if(map1[x][y]==-1||map1[x][y]!=-1&&map1[x][y]<z)
            map1[x][y]=z;
    }
    for(int i=1; i<=n; i++)
        if(!in[i])
            DFS(i);
    cout<<maxx<<'\n';
    return 0;
}
           

Problem D: Down the Pyramid

Do you like number pyramids? Given a number sequence that represents the base, you are

usually supposed to build the rest of the “pyramid” bottom-up: For each pair of adjacent

numbers, you would compute their sum and write it down above them. For example, given the

base sequence [1, 2, 3], the sequence directly above it would be [3, 5], and the top of the pyramid

would be [8]:

1 2 3

3 5

8

However, I am not interested in completing the pyramid – instead, I would much rather go

underground. Thus, for a sequence of n non-negative integers, I will write down a sequence of

n + 1 non-negative integers below it such that each number in the original sequence is the sum

of the two numbers I put below it. However, there may be several possible sequences or perhaps

even none at all satisfying this condition. So, could you please tell me how many sequences

there are for me to choose from?

Input

The input consists of:

• one line with the integer n (1 ≤ n ≤ 106

), the length of the base sequence.

• one line with n integers a1, . . . , an (0 ≤ ai ≤ 108

for each i), forming the base sequence.

Output

Output a single integer, the number of non-negative integer sequences that would have the input

sequence as the next level in a number pyramid.

Sample Input 1 Sample Output 1

6

12 5 7 7 8 4

2

Sample Input 2 Sample Output 2

3

10 1000 100

GCPC 2018 – Problem D: Down the Pyramid

题意:给一个数字三角形的一层,问他的下一层有多少种取法

思路 :简单的规律题。从左到右,更新能选的数的上下界up & down,同时更新答案 = up - down + 1

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e6+2;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };

ll a[maxn];

int main()
{
    ll n;
    cin>>n;
    rep(i,1,n) scanf("%lld",&a[i]);
    ll ans = a[1]+1;
    ll up = a[1];
    ll down = 0;
    rep(i,2LL,n)
    {
        ll t1 = up;
        ll t2 = down;
        up = a[i]-t2;
        down = max(a[i]-t1,0);
        if(up<0)
        {
            ans = 0;
            break;
        }
        ans = abs(up-down+1);
    }
    cout<<ans<<endl;
    return 0;
}

           

Problem E: Expired License

Paul is an extremely gifted computer scientist who just completed his master’s degree at a

prestigious German university. Now he would like to culminate his academic career in a PhD.

The problem is that there are so many great universities out there that it is hard for him to

pick the best. Because some application deadlines are coming up soon, Paul’s only way to

procrastinate his decision is by simply applying to all of them.

Most applications require Paul to attach a portrait photo. However, it seems like there does

not exist an international standard for the aspect ratio of these kinds of photos. While most

European universities ask Paul to send a photograph with aspect ratio 4.5 by 6, some Asian

countries discard the applications immediately if the photo does not have an aspect ratio of 7.14

by 11.22, precisely.

As Paul has never been interested in photo editing, he never had a reason to spend a lot of money

on proper software. He downloaded a free trial version some months ago, but that version

has already expired and now only works with some funny restrictions. The cropping tool, for

example, no longer accepts arbitrary numbers for setting the aspect ratio, but only primes. This

makes Paul wonder whether the desired aspect ratios can even be properly expressed by two

prime numbers. Of course, in case this is possible, he would also like to know the primes he has

to enter.

Input

The input consists of:

• one line with an integer n (1 ≤ n ≤ 105

), the number of applications Paul has to file;

• n lines, each with two real numbers a and b (0 < a, b < 100), where a × b is the desired

aspect ratio of one application.

All real numbers are given with at most 5 decimal places after the decimal point.

Output

For each application, if it is possible to represent the desired aspect ratio by two prime numbers

p and q, output one line with p and q. Otherwise, output impossible. If multiple solutions

exist, output the one minimizing p + q.

Sample Input 1 Sample Output 1

3

4.5 6

7.14 11.22

0.00002 0.00007

impossible

7 11

2 7

GCPC 2018 – Problem E: Expired License

题意:问题给一个小数能否表示成两个素数比值

思路:队友A的,先累x10转成整数比值,然后对这两个数求最大公约数,判断是否为素数,特判相等时输出2:2。

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
//#include<random>
#include<cstdlib>
#include<ctime>
#include<map>
#include<stack>
#include<queue>
#define FAST ios::sync_with_stdio(false)
#define DEV_RND ((int)rand()*RAND_MAX+rand())
#define RND(L,R) (DEV_RND%((R)-(L)+1)+(L))
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<n;++i)
#define per(i,n,a) for(int i=n-1;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define li inline
#define re register
using namespace std;
//typedef uniform_int_distribution<int> RNDI;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef double db;
typedef long long ll;
typedef long double ld;
const int maxn = 1e5+5;
const int maxm = 100000+5;
const int mod = 1e9+7;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1);
//int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
//li int f(int x){return x==par[x]?par[x]:par[x]=f(par[x]);}
//mt19937 eng(time(0));
//li int RND(int L,int R){RNDI rnd(L,R);return rnd(eng);}
li ll lowbit(ll x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
li ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res%MOD;}
li ll qmul(ll a,ll b,ll MOD=mod){return (a*b-(ll)((long double)a/MOD*b)*MOD+MOD)%MOD;}
li ll inv(ll x,ll p){return qpow(x,p-2,p);}
namespace IO
{
	li ll read()
	{
		ll x=0,sign=1;char c=getchar();
		while(c>'9'||c<'0') {if(c=='-') sign=-1;c=getchar();}
		while('0'<=c&&c<='9') x=x*10+c-'0',c=getchar();
		return x*sign;
	}
	template<typename T>
	li void write(T x,char t='\n')
	{
		if(x<0){x=-x;putchar('-');};
		static int sta[25];int top=0;
		do{sta[top++]=x%10;}while(x/=10);
		while(top) putchar(sta[--top]+'0');
		putchar(t);
	}
}
using namespace IO;
/*-------------head-------------*/
//
//map<int,int> fac1,fac2;
bool is_prime(int x)
{
	if(x==1||x==0) return false;
	int n=sqrt(x);
	rep(i,2,n+1) if(!(x%i)) return false;
	return true;
}
int n,m,a,b;
string num1,num2;
li void solve()
{
	cin>>num1>>num2;
	//fac1.clear(),fac2.clear();
	bool flag=0;
	int cnt1=0,cnt2=0;
	rep(i,0,sz(num1))
	{
		if(flag==true) cnt1++;
		if(num1[i]=='.') flag=true;
	}
	if(!flag) num1.append(1,'.');
	flag=0;
	rep(i,0,sz(num2))
	{
		if(flag==true) cnt2++;
		if(num2[i]=='.') flag=true;
	}
	if(!flag) num2.append(1,'.');
	//
	int t=max(cnt1,cnt2);
	a=b=0;
	rep(i,0,sz(num1))
	{
		if(num1[i]=='.') continue;
		a=a*10+num1[i]-'0';
	}
	rep(i,0,sz(num2))
	{
		if(num2[i]=='.') continue;
		b=b*10+num2[i]-'0';
	}
	while(cnt1++<t) a*=10;
	while(cnt2++<t) b*=10;
	//
	if(a==b) {write(2,' '),write(2);return;}
	int d=gcd(a,b);
	a/=d;b/=d;
	//
	if(is_prime(a)&&is_prime(b)) write(a,' '),write(b);
	else puts("impossible");
	//puts("");
}
int main()
{
	//srand(time(0));
	//freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
	for(int QwQ=read();QwQ;QwQ--) solve();
	//while(~scanf("%d",&n)) solve();
	return 0;
}
           

Problem F: Fighting Monsters

Emma just discovered a new card game called Gwint: A wizard’s game. There are two types of

cards: monster cards and spell cards. Monster cards are used to score points, while spell cards

typically interact with the monsters in some way.

On each monster card there is an integer value, the power of the monster. Monsters can fight each

other, and during these fights the power acts as both the strength and the health of the monster.

The monsters take turns hitting each other until one of them dies. Whenever a monster A hits a

monster B, this causes B to lose an amount of power equal to the power of A. Conversely, if B

hits A, A loses power equal to the power of B (see the example below). This continues until one

of the two monsters has a power of zero or less, at which point this monster is considered dead.

A B

4 → 7

4 ← 3

1 → 3

1 ← 2

-1 2

Images by OpenClipart-Vectors on Pixabay and from PhantomOpenEmoji.

Figure F.1: A fight between monsters A and B, starting with powers of

4 and 7, respectively. A hits first. B wins with a remaining power of 2.

One of Emma’s most beloved cards in the game is a spell called Fight! which states:

Pick two monsters. They fight each other to the death. If the surviving monster has

a power of exactly 1 left, return this card to your hand.

Of course, Emma would like to play as efficiently as possible by picking two monsters such that

Fight! is returned to her hand. However, there are often a lot of monsters on the board, which

makes it very time consuming to figure out whether this can be done or not. Can you help her

find two monsters she can pick so that she gets the card back?

Input

The input consists of:

• one line with an integer n (2 ≤ n ≤ 105

), the number of monsters;

• one line with n integers m1, . . . , mn (1 ≤ mi ≤ 106

), giving the power of each monster.

Output

If there is no pair of monsters that Emma can pick, output impossible. Otherwise, output

two distinct integers i, j (1 ≤ i, j ≤ n), where i is the index of the monster that starts the fight

and j is the index of the other monster. If multiple solutions exist, any of them will be accepted.

GCPC 2018 – Problem F: Fighting Monsters

题意:问序列里面能不能找出两个数,互相让减去自己的值后变成一个1一个小于等于0

思路:拿几个数据试一下就发现只能是斐波那契数且相邻才能满足题意。因为最后一个状态一定是1 1然后一个把另一个变成0。那么就存一下斐波那契数即可

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e5+2;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };

map<ll,ll> Map;
ll f[100];
ll a[maxn];

typedef struct Pos
{
    ll idx;
    ll pos;
} P;

bool cmp(P a, P b)
{
    return a.idx < b.idx;
}

P c[maxn];

void init()
{
      Map[1] = 1;
      Map[2] = 2;
      f[1] = 1, f[2] = 1;
      for(int i=3;i<=40;i++)
      {
          f[i] = f[i-1] + f[i-2];
          Map[f[i]] = i;
      }
}


int main()
{
    init();
    ll n;
    cin>>n;
    rep(i,1,n) scanf("%lld",&a[i]);
    ll cnt = 0;
    ll aa=0,bb=0;
    rep(i,1,n)
    {
        if(a[i]==1)
        {
            cnt++;
            if(cnt==1) aa = i;
            else bb = i;
        }
        c[i].idx = Map[a[i]];
        c[i].pos = i;
    }
    if(cnt>=2)
    {
        cout<<aa<< ' '<<bb<<'\n';
        return 0;
    }
    sort(c+1,c+1+n,cmp);
    rep(i,2LL,n)
    {
        if(c[i].idx-c[i-1].idx==1&&c[i].idx!=0&&c[i-1].idx!=0)
        {
            cout<<c[i-1].pos<<' '<<c[i].pos<<'\n';
            return 0;
        }
    }
    cout<<"impossible"<<endl;
    return 0;
}

           

Problem H: Hyper Illuminati

Once again the time dawns to demonstrate the sheer power of the Illuminati. To do so, it was

decided to build an n-dimensional hyper-step pyramid using n-dimensional blocks:

• All the steps of the pyramid are n-dimensional hyper-cuboids.

• Every step has a height of exactly 1 block in the n-th dimension.

• The pyramid has s steps and the base step is s blocks long in every other of the n − 1

dimensions.

• Every subsequent higher step is 1 block shorter in each of the n − 1 dimensions than the

step below it.

• The top step is exactly 1 block.

To prove their might even further the Illuminati leaders have decided to add two more requirements:

• n must be at least 3.

• The number of blocks used to build the pyramid must be a meaningful number.

Figure H.1: A 3-dimensional hyper pyramid with 3 steps consisting of 14 blocks in total.

Input

The input consists of:

• one line with a single integer m (1 ≤ m ≤ 1016) . This integer is the meaningful number

the leaders have chosen.

Output

If a hyper-step pyramid matching all the requirements exists, output a single line with two

integers n and s, the dimension of the pyramid and its number of steps. If none exists, output

impossible. If multiple solutions exist, any will be accepted.

Sample Input 1 Sample Output 1

14 3 3

Sample Input 2 Sample Output 2

9 4 2

GCPC 2018 – Problem H: Hyper Illuminati 15

Sample Input 3 Sample Output 3

24 impossible

Sample Input 4 Sample Output 4

9134731356568978 5 2147

题意:求一对n,s。使得i从1到s,累加i的n-1次方等于n

指数跨度很大,所以枚举的范围其实很小,暴力一下就出来了。

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 3e4+2;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e18;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };

ll quick_pow(ll x, ll y)
{
        if(!y)  return 1;
        ll ans = quick_pow(x,y>>1);
        ans *= ans;
        if(y&1)  ans *= x;
        return ans;
}

int main()
{
    ll n;
    cin>>n;
    per(i,55,3)
    {
        ll ans = 0;
        rep(j,1,1000000)
        {
            ans += quick_pow(j,i-1);
            if(ans==n)
            {
                cout<<i<<' '<<j<<endl;
                return 0;
            }
            if(ans>n) break;
        }
    }
    cout<<"impossible"<<endl;
    return 0;
}

           

Problem I: It’s Time for a Montage

题意:每次可以给a数列都+1,问最少加多少次可以使得a的字典序比b大

思路:优先看前面的,如果相等就往后看,遇到小于就把最开头的相等情况多加1,有大于的直接返回

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e3+5;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0',  ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };

ll a[maxn];
ll b[maxn];

int main()
{
    ll n; cin>>n;
    rep(i,1,n)
    cin>>a[i];
    rep(i,1,n) cin>>b[i];
    ll ans = max(b[1]-a[1],0LL);
    if(b[1]<a[1])
    {
        cout<<0<<endl;
        return 0;
    }
    rep(i,2,n)
    {
        if(a[i]+ans==b[i]) continue;
        else if(a[i]+ans>b[i])  break;
        ans++;
        break;
    }
    cout<<ans<<endl;
    return 0;
}

           

Problem L: Logic Puzzle

题意:指示出h x w矩阵里面的地雷

从左上角开始找,因为(1,1)只能唯一确定矩阵 左上角的元素是否为地雷,往后每次可以多确定一个,依次遍历每一层标记地雷位置,详见代码

#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
using namespace std;
#define ll long long
#define maxn 0x3f3f3f3f
int read()
{
    int sign=1,ans=0;
    char ch;
    ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            sign=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        ans=(ans<<1)+(ans<<3)+(ch^48);
        ch=getchar();
    }
    return ans*sign;
}
int map1[105][105];
int ans[105][105];
int main()
{
    memset(ans,0,sizeof(ans));
    int n,m;
    cin>>n>>m;
    for(int i=1; i<=n+2; i++)
        for(int j=1; j<=m+2; j++)
            map1[i][j]=read();
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            if(map1[i][j]>0)
            {
                ans[i][j]=1;
                map1[i][j+1]--;
                map1[i][j]--;
                map1[i][j+2]--;
                map1[i+1][j+1]--;
                map1[i+1][j+2]--;
                map1[i+1][j]--;
                map1[i+2][j+1]--;
                map1[i+2][j+2]--;
                map1[i+2][j]--;
            }
            else if(map1[i][j]<0)
            {
                cout<<"impossible"<<'\n';
                return 0;
            }
        }
        for(int k=1; k<=m+2; k++)
        {
            if(map1[i][k]!=0)
            {
                cout<<"impossible"<<'\n';
                return 0;
            }
        }
    }
    for(int i=n; i<=n+2; i++)
    {
        for(int j=1; j<=m+2;j++)
        {
            if(map1[i][j]!=0)
            {
                cout<<"impossible"<<'\n';
                return 0;
            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            if(ans[i][j]==1)
                cout<<"X";
            else
                cout<<".";
        }
        cout<<'\n';
    }
    return 0;
}