2016-2017 ACM-ICPC Southeastern European Regional Programming Contest (SEERC 2016)

题目链接  Codefores_Gym_101164

Solved  6/11

Penalty 1652

Problem A

Problem B

Problem C

Problem D

Problem E

Problem F

预处理出一个pre数组

pre[i]表示i位字母数以内用掉多少个字母

然后就可以算出要计算的位置是第多少个字母数

最后就是转成26进制了

注意是没有0有26的26进制

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<string>
 8 #include<vector>
 9 #include<map>
10 #include<set>
11 #include<queue>
12 using namespace std;
13 int n;
14 int siz[11],pre[11],ans[11];
15 int main()
16 {
17     //freopen("F.in","r",stdin);
18     siz[1]=26;
19     siz[2]=26*26+26;
20     siz[3]=26*26*26+26*26+26;
21     siz[4]=26*26*26*26+26*26*26+26*26+26;
22     siz[5]=siz[4]+26*26*26*26*26;
23     siz[6]=siz[5]+26*26*26*26*26*26;
24     pre[1]=siz[1];
25     pre[2]=pre[1]+(siz[2]-siz[1])*2;
26     pre[3]=pre[2]+(siz[3]-siz[2])*3;
27     pre[4]=pre[3]+(siz[4]-siz[3])*4;
28     pre[5]=pre[4]+(siz[5]-siz[4])*5;
29     pre[6]=pre[5]+(siz[6]-siz[5])*6;
30     while (~scanf("%d",&n))
31     {
32         n++;
33         int i;
34         for (i=6;i>=0;i--)
35             if (n>pre[i]) break;
36         int pos=i;
37         n=n-pre[pos];
38         int nxt=n/(pos+1);
39         int rest=n%(pos+1);
40         if (rest!=0) nxt++;
41         else rest=pos+1;
42         n=siz[pos]+nxt;
43         memset(ans,0,sizeof(ans));
44         int cnt=pos+1;
45         while (cnt--)
46         {
47             ans[cnt+1]+=n%26;
48             if (ans[cnt+1]==0)
49             {
50                 ans[cnt+1]=26;
51                 ans[cnt]--;
52             }
53             n=n/26;
54         }
55         printf("%c\n",'A'+(ans[rest]-1));        
56     }
57     return 0;
58 }
View Code

 

Problem G

Problem H

可以发现一定可以把所有的点连起来

因此可以不断的建立凸包

然后用一条边把外面的大凸包和里面的小凸包连起来

为了确保连成螺旋形

在建立里面的小凸包时将上一个大凸包最后一个点也加进去

然后依次连接即可

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstdlib>
  5 #include<algorithm>
  6 #include<cstring>
  7 #include<string>
  8 #include<vector>
  9 #include<map>
 10 #include<set>
 11 #include<queue>
 12 using namespace std;
 13 #define y1 khjk
 14 #define y2 kjkj
 15 const double pi=acos(-1.0);
 16 struct point
 17 {
 18     double x,y;
 19     int id;
 20     point(){}
 21     point(double _x,double _y):x(_x),y(_y)
 22     {}
 23     point operator -(const point &b) const
 24     {
 25         return point(x-b.x,y-b.y);
 26     }
 27     double operator *(const point &b) const
 28     {
 29         return x*b.x+y*b.y;
 30     }
 31     double operator ^(const point &b) const
 32     {
 33         return x*b.y-y*b.x;
 34     }
 35     bool operator <(const point &b) const
 36     {
 37         return y<b.y||(y==b.y&&x<b.x);
 38     }
 39 };
 40 double cross(point sp,point ep,point op)
 41 {
 42     //cout<< (sp.x-op.x)*(ep.y-op.y)-(sp.y-op.y)*(ep.x-op.x)<<endl;
 43     return (sp.x-op.x)*(ep.y-op.y)-(sp.y-op.y)*(ep.x-op.x);
 44 }
 45 int n,L;
 46 point p[5010],s[5010],u[5010],as[5010],w[5010];
 47 int ans[5010],id[5010],nid[5010];
 48 bool used[5010];
 49 bool cmp(const point &a, const point &b)//逆时针排序
 50 {
 51     point origin=s[1];
 52     return cross(a,b,origin)> 0;
 53 }
 54 
 55 int convex(int n)
 56 {
 57     int i, len, top = 2;
 58     //cout<<"hhhHH"<<endl;
 59     sort(p+1, p + n+1);
 60     if(n == 0)  return 1;   s[1] = p[1];
 61     if(n == 1)  return 2;   s[2] = p[2];
 62     if(n == 2)  return 3;   s[3] = p[3];
 63     
 64     for(int i = 3; i <=n; i++)
 65     {
 66         while(top >1&& cross(s[top], s[top - 1],p[i])>0)  top--;
 67         s[++top] = p[i];
 68         //cout<<top<<" "<<id[i]<<endl;
 69     }
 70     
 71     len = top;  s[++top] = p[n - 1];
 72     
 73     for(int i = n - 2; i >= 1; i--)
 74     {
 75         while(top!=len && cross(s[top], s[top - 1],p[i])>0)  top--;
 76         s[++top] = p[i];
 77         //cout<<top<<" "<<id[i]<<endl;
 78     }
 79     return top;
 80 }
 81 double dis(point a,point b)
 82 {
 83     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
 84 }
 85 int main()
 86 {
 87     int fg=1;
 88     while (~scanf("%d",&n))
 89     {
 90         int i;
 91         for (i=1;i<=n;i++)
 92         {
 93             double x,y;
 94             scanf("%lf%lf",&x,&y);
 95             p[i]=point(x,y);
 96             p[i].id=i;
 97             w[i]=p[i];
 98         }    
 99         int rest=n;
100         memset(used,false,sizeof(used));
101         int cnt=convex(n);
102         cnt--;
103         int ct=0;
104         //sort(s+2,s+cnt+1,cmp);
105         for (i=1;i<=cnt;i++)
106             ans[++ct]=s[i].id,used[s[i].id]=true,as[ct]=s[i];
107         while (cnt<rest)
108         {
109             rest=1;
110             u[rest]=as[ct];
111             //cout<<as[ct].id<<endl;
112             int id=as[ct].id;
113             ct--;
114             for (i=1;i<=n;i++)
115                 if (!used[i])
116                     u[++rest]=w[i];
117             for (i=1;i<=rest;i++)
118                 p[i]=u[i];//cout<<p[i].id<<" ";
119             //cout<<endl;
120             cnt=convex(rest);
121             cnt--;
122             //sort(s+2,s+cnt+1,cmp);
123             for (i=1;i<=cnt;i++)
124                 if (s[i].id==id) break;
125             //cout<<cnt<<endl;
126             //for (int j=1;j<=cnt;j++)
127             //    cout<<s[j].id<<" ";
128             //cout<<endl;
129             int now=i;
130             for (i=1;i<=cnt;i++)
131             {
132                 ans[++ct]=s[now].id;
133                 as[ct]=s[now];
134                 used[s[now].id]=true;
135                 now++;
136                 if (now==cnt+1) now=1;
137             }
138         }
139         printf("%d\n",n);
140         for (i=1;i<n;i++)
141             printf("%d ",ans[i]);
142         printf("%d\n",ans[n]);
143     }
144     return 0;
145 }
View Code

 

Problem I打表发现ans <= 9

考虑BFS

不必把所有的状态都存进去

只要存能取的最大数的前面70个即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<string>
 8 #include<vector>
 9 #include<map>
10 #include<set>
11 #include<queue>
12 using namespace std;
13 struct ss
14 {
15     int x,fa,y;
16 };
17 ss q[10000100];
18 int h,t,n;
19 bool b[44777445];
20 int ans[110];
21 inline bool cmp(int x,int y)
22 {
23     return x>y;
24 }
25 void push(int x,int y)
26 {
27     if (b[x]) return;
28     b[x]=true;
29     t++;
30     q[t].fa=h;
31     q[t].x=x;
32     q[t].y=y;
33     if (x==n)
34     {
35         int i=0,k=t;
36         while (k!=0)
37         {
38             i++;
39             ans[i]=q[k].y;
40             k=q[k].fa;
41         }
42         printf("%d\n",i-1);
43         sort(ans+1,ans+i+1,cmp);
44         int j;
45         for (j=1;j<i-1;j++)
46             printf("%d ",ans[j]);
47         printf("%d\n",ans[i-1]);
48         exit(0);
49     }
50 }
51 int main()
52 {
53     scanf("%d",&n);
54     h=0;
55     t=1;
56     q[1].fa=0;
57     q[1].x=0;
58     q[1].y=0;
59     while (h<t)
60     {
61         h++;
62         int x=q[h].x;
63         int rest=n-x;
64         int i;
65         int l=1,r=360;
66         while (l<=r)
67         {
68             int mid=(l+r)>>1;
69             if (mid*mid*mid>rest)
70                 r=mid-1;
71             else l=mid+1;
72         }
73         int p=l-1;
74         for (i=p;i>=max(1,p-70);i--)
75             push(x+i*i*i,i);
76     }
77     return 0;
78 }
View Code

 

Problem J

Problem K

考虑字符串Hash

枚举两个断点,然后分成三段,总共有6个不同的排列。

对于每一段用预处理的Hash,O(1)判断即可。

有解就退出

 

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)

typedef long long LL;

const int N  = 5010;
const LL mod = 1e9 + 7;

LL base = 1e10 + 3;
LL sHash[N], sbin[N];
LL tHash[N], tbin[N];
int n;
char s[N], t[N];
LL cc[N];
int yy[N];



void sHashtable(){
	sbin[0] = 1LL;
	rep(i, 1, n) sbin[i] = (sbin[i - 1] * base);
	rep(i, 1, n) sHash[i] = (sHash[i - 1] * base + s[i]);
}

inline LL sgethash(const int &l, const int &r){
	return (sHash[r] - sHash[l - 1] * sbin[r - l + 1]);
}


void tHashtable(){
	tbin[0] = 1LL;
	rep(i, 1, n) tbin[i] = (tbin[i - 1] * base);
	rep(i, 1, n) tHash[i] = (tHash[i - 1] * base + t[i]);
}

inline LL tgethash(const int &l, const int &r){
	return (tHash[r] - tHash[l - 1] * tbin[r - l + 1]);
}

void print(int l1, int r1, int l2, int r2, int l3, int r3){
	puts("YES");
	rep(i, l1, r1) putchar(t[i]); putchar(10);
	rep(i, l2, r2) putchar(t[i]); putchar(10);
	rep(i, l3, r3) putchar(t[i]); putchar(10);
	exit(0);
}


int main(){


	scanf("%s", s + 1);
	n = strlen(s + 1);

	rep(i, 0, n) cc[i] = (LL)rand() * (LL)rand() * (LL)rand();

	rep(i, 1, n) if (s[i] < 'a') s[i] = s[i] - 'A' + 'a';
	scanf("%s", t + 1);
	rep(i, 1, n) if (t[i] < 'a') t[i] = t[i] - 'A' + 'a';


	sHashtable();
	tHashtable();



	rep(i, 1, n - 2){
		dec(j, n, i + 2){

			int l1 = 1, r1 = i;
			int l2 = i + 1, r2 = j - 1;
			int l3 = j, r3 = n;

			int c1 = r1 - l1 + 1;
			int c2 = r2 - l2 + 1;
			int c3 = r3 - l3 + 1;

			if (sgethash(1, c1) == tgethash(l1, r1)){
				if (sgethash(c1 + 1, c1 + c2) == tgethash(l2, r2)){
					if (sgethash(c1 + c2 + 1, n) == tgethash(l3, r3)){
						print(l1, r1, l2, r2, l3, r3);
					}
				}
			}

			swap(l2, l3);
			swap(r2, r3);
			swap(c2, c3);
			if (sgethash(1, c1) == tgethash(l1, r1)){
				if (sgethash(c1 + 1, c1 + c2) == tgethash(l2, r2)){
					if (sgethash(c1 + c2 + 1, n) == tgethash(l3, r3)){
						print(l1, r1, l2, r2, l3, r3);
					}
				}
			}

			swap(l2, l1);
			swap(r2, r1);
			swap(c2, c1);

			if (sgethash(1, c1) == tgethash(l1, r1)){
				if (sgethash(c1 + 1, c1 + c2) == tgethash(l2, r2)){
					if (sgethash(c1 + c2 + 1, n) == tgethash(l3, r3)){
						print(l1, r1, l2, r2, l3, r3);
					}
				}
			}

			swap(l2, l3);
			swap(r2, r3);
			swap(c2, c3);
			if (sgethash(1, c1) == tgethash(l1, r1)){
				if (sgethash(c1 + 1, c1 + c2) == tgethash(l2, r2)){
					if (sgethash(c1 + c2 + 1, n) == tgethash(l3, r3)){
						print(l1, r1, l2, r2, l3, r3);
					}
				}
			}


			swap(l2, l1);
			swap(r2, r1);
			swap(c2, c1);

			if (sgethash(1, c1) == tgethash(l1, r1)){
				if (sgethash(c1 + 1, c1 + c2) == tgethash(l2, r2)){
					if (sgethash(c1 + c2 + 1, n) == tgethash(l3, r3)){
						print(l1, r1, l2, r2, l3, r3);
					}
				}
			}


			swap(l2, l3);
			swap(r2, r3);
			swap(c2, c3);
			if (sgethash(1, c1) == tgethash(l1, r1)){
				if (sgethash(c1 + 1, c1 + c2) == tgethash(l2, r2)){
					if (sgethash(c1 + c2 + 1, n) == tgethash(l3, r3)){
						print(l1, r1, l2, r2, l3, r3);
					}
				}
			}
		}
	}

	puts("NO");
	return 0;
}

 

转载于:https://www.cnblogs.com/cxhscst2/p/7629481.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值