2017-10-06清北模拟赛

NOIP 模拟赛
2017 年10 ⽉6 ⽇
题⽬名称排序同余⽅程组字符串
可执⾏⽂件名sort mod str
输⼊⽂件名sort.in mod.in str.in
输出⽂件名sort.out mod.out str.out
每个测试点时限1 秒1 秒1 秒
内存限制256MB 256MB 256MB
测试点数⽬10 10 10
每个测试点分值10 10 10
是否有Special Judge ⽆⽆⽆
题⽬类型传统型传统型传统型
是否有附加⽂件否否否
C++ 语⾔⽂件名后缀cpp cpp cpp
C 语⾔⽂件名后缀c c c
Pascal 语⾔⽂件名后缀pas pas pas
编译开关
对于C++ 语⾔-lm
对于C 语⾔-lm
对于Pascal 语⾔-lm


T1 排序

sort.in/.out/.cpp
【问题描述】
⼩Z 有⼀个数字序列a1; a2; : : : ; an,长度为n,⼩Z 只有⼀个操作:选
定p(1  p  n),然后把ap 从序列⾥拿出,然后再插⼊到序列中任意位置。
⽐如a 序列为1,2,4,5,3,p = 5,可以取出3,然后在任意位置插⼊,可
以变为1,2,3,4,5。
现在给你⼀个序列a,问你是否可以通过⼀次操作把整个序列从⼩到⼤
排好序(变成不降的)。
【输入格式】
第⼀⾏⼀个整数n,第⼆⾏空格隔开的n 个整数,代表a 序列。
【输出格式】
如果可以⼀次操作可以排好序,输出”YES”,否则输出”NO”。
【样例输入】
5
1 2 4 5 3
【样例输出】
YES
【数据规模和约定】
对于30% 的数据,满⾜n  1000。
对于60% 的数据,满⾜n  105。
对于100% 的数据,满⾜n  106; 1  ai  106。
2

 1 /*
 2 要求判断调整后的序列是否可以成为非严格单调递增的
 3 sort一下 因为要求只调换一个数字的位置
 4 可以发现只能有一个数向后或向前,移动,或者是没有数字移动
 5 (排序前后的位置) 
 6 */
 7 #include <algorithm>
 8 #include <cstdio>
 9 
10 inline void read(int &x)
11 {
12     x=0; register char ch=getchar();
13     for(; ch>'9'||ch<'0'; ) ch=getchar();
14     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
15 }
16 const int N(1e6+5);
17 int n,cnt1,cnt2;
18 struct Sort {
19     int num,pos;
20     bool operator < (const Sort &x)const
21     {
22         if(num!=x.num) return num<x.num;
23         return pos<x.pos;
24     }
25 }a[N];
26 
27 int Presist()
28 {
29 //    freopen("sort.in","r",stdin);
30 //    freopen("sort.out","w",stdout);
31     read(n);
32     for(int i=1; i<=n; ++i)
33         read(a[i].num),a[i].pos=i;
34     std::sort(a+1,a+n+1);
35     for(int i=1; i<=n; ++i)
36     {
37         if(a[i].pos>i) cnt1++;
38         if(a[i].pos<i) cnt2++;
39     }
40     if(cnt1==1||cnt2==1||(!cnt2&&!cnt1)) puts("YES");
41     else puts("NO");
42     return 0;
43 }
44 
45 int Aptal=Presist();
46 int main(int argc,char*argv[]){;}
AC

 

 

 


T2 同余方程组

 

mod.in/.out/.cpp

【问题描述】
求关于x 的同余⽅程组
x%a1 = b1
x%a2 = b2
x%a3 = b3
x%a4 = b4
的⼤于等于0 的最⼩整数解。
【输入格式】
⼀⾏8 个整数,表⽰a1; b1; a2; b2; a3; b3; a4; b4。
【输出格式】
⼀⾏⼀个整数,答案除以p 的余数。
【样例输入】
2 0 3 1 5 0 7 3
【样例输出】
10
【数据规模和约定】
对于30% 的数据,ai  40, 保证ai 均为素数。
3
对于60% 的数据,1  ai  103, 保证ai 均互素。
对于100% 的数据,0  bi < ai; 1  ai  103。
4

 1 /*
 2 CRT不互质情况 的模板 
 3 */
 4 #include <cstdio>
 5 
 6 #ifdef WIN32
 7 #define L_ "%I64d"
 8 #else
 9 #define L_ "%lld"
10 #endif
11 #define LL long long
12 inline void read(LL &x)
13 {
14     x=0; register char ch=getchar();
15     for(; ch>'9'||ch<'0'; ) ch=getchar();
16     for(; ch>='0'&&ch<='9'; ch=getchar()) x=x*10+ch-'0';
17 }
18 LL p[5],m[5];
19 
20 LL exgcd(LL a,LL b,LL &x,LL &y)
21 {
22     if(!b) { x=1,y=0; return a; }
23     LL ret=exgcd(b,a%b,x,y),tmp=x;
24     x=y; y=tmp-a/b*y; return ret;
25 }
26 inline LL CRT()
27 {
28     LL x,y,b,c,gcd,tmp;
29     LL ret=m[1],a=p[1],mod;
30     for(int i=2; i<5; ++i)
31     {
32         tmp=m[i];b=p[i];c=tmp-ret;
33         gcd=exgcd(a,b,x,y);
34         x*=c/gcd; mod=b/gcd;
35         x=(x%mod+mod)%mod;
36         ret+=a*x; a*=mod;
37     }
38     return ret?ret:(ret+a);
39 }
40 
41 int Presist()
42 {
43 //    freopen("mod.in","r",stdin);
44 //    freopen("mod.out","w",stdout);
45     for(int i=1; i<5; ++i)
46         read(p[i]),read(m[i]);
47     printf(L_ "\n",CRT());
48     return 0;
49 }
50 
51 int Aptal=Presist(); 
52 int main(int argc,char**argv){;}
AC

 


T3 字符串

str.in/.out/.cpp

【问题描述】

如果把⼀个字符串从头到尾翻转后和原字符串相等,我们称之为回⽂
串,⽐如“aabaa”、“())(”、“2017102”。
如果⼀个字符串存在两个出现过的字母出现的次数相等,我们称之为好
的字符串。
现在给⼀个由⼩写字母组成的字符串,问在这个字符串的所有连续⼦串
中,好的回⽂串有多少个。(两个相同的回⽂串出现在不同位置算多次)。
【输入格式】
⼀⾏⼀个⼩写字母组成的字符串。
【输出格式】
⼀⾏⼀个整数,表⽰答案。
【样例输入】
abcbaabcba
【样例输出】
6
【样例解释】
abcba s[1..5] a,b 出现次数相等
baab s[4..7] a,b 出现次数相等
cbaabc s[3..8] a,b 出现次数相等
bcbaabcb s[2..9] a,c 出现次数相等
5
abcbaabcba s[1..10] a,b 出现次数相等
abcba s[6..10] a,b 出现次数相等
【数据规模和约定】
len 表⽰字符串长度。
对于30% 的数据, len  102。
对于60% 的数据, len  103。
对于100% 的数据,1  len  104。
6
(完)
7

 

 1 #include <algorithm>
 2 #include <cstring>
 3 #include <cstdio>
 4 
 5 const int N(1e4+5);
 6 int n,ans,tmp[26];
 7 char s[N];
 8 
 9 int Presist()
10 {
11 //    freopen("str.in","r",stdin);
12 //    freopen("str.out","w",stdout);
13     scanf("%s",s+1); n=strlen(s+1);
14     for(int l=1; l<n; ++l)
15       for(int r=l+1; r<=n; ++r)
16       {
17           if(r-l+1<4) continue;    //判断是否可能存在至少两种相同次数的不同字母 
18           memset(tmp,0,sizeof(tmp)); //memset复发度o(n),数组开大就是30,该刚好就60 
19           for(int i=l,j=r; i<=j; i++,j--)
20           {
21               if(s[i]!=s[j]) goto love;
22               if(i==j) tmp[s[i]-'a']++; //长度奇数,中间的只会有统计一次 
23               else    tmp[s[i]-'a']+=2;
24         }
25         std::sort(tmp,tmp+26);
26         for(int k=1; k<26; ++k)
27          if(tmp[k]>1&&tmp[k]==tmp[k-1]) { ans++; break; }
28         love:;
29       } 
30     printf("%d\n",ans);
31     return 0;
32 }
33 
34 int Aptal=Presist();
35 int main(int argc,char**argv){;}
60分暴力

 

  1 /*
  2 hash
  3 */
  4 #include <cstdio>
  5 #include <cstring>
  6 #include <algorithm>
  7 #include <map>
  8 using namespace std;
  9 
 10 typedef unsigned long long ULL;
 11 typedef long long LL;
 12 
 13 char s[10005];
 14 ULL h[10005],rh[10005],pw[10005];
 15 int L;
 16 
 17 ULL hs(int l,int r)
 18 {
 19     return h[r]-h[l-1]*pw[r-l+1];
 20 }
 21 ULL rhs(int l,int r)
 22 {
 23     return rh[l] - rh[r+1]*pw[r-l+1];
 24 }
 25 struct N
 26 {
 27     int a[26];
 28     bool ok()
 29     {
 30         int b[26];
 31         for(int i=0; i<26; i++) b[i]=a[i];
 32         sort(b,b+26);
 33         for(int i=0; i<25; i++)
 34         {
 35             if(b[i]>0&& b[i] == b[i+1]) return true;
 36         }
 37         return false;
 38     }
 39     void clear()
 40     {
 41         memset(a,0,sizeof a);
 42     }
 43 };
 44 LL ans=0;
 45 map<ULL,LL> num;
 46 map<ULL,N> A;
 47 void solve_odd()
 48 {
 49     for(int i=1; i<=L; i++)
 50     {
 51         int l = 1,r = min(i,L-i+1)+1;
 52         while(r-l>1)
 53         {
 54             int mid = (l+r)/2;
 55             if(hs(i-mid+1,i+mid-1)== rhs(i-mid+1,i+mid-1)) l=mid;
 56             else r=mid;
 57         }
 58         int p=l;
 59         int tmp = p;
 60         while(tmp>=1&&num.find(hs(i-tmp+1,i+tmp-1))==num.end()) tmp--;
 61         LL sum = 0;
 62         N st;
 63         st.clear();
 64         if(tmp>=1)
 65         {
 66             sum=num[hs(i-tmp+1,i+tmp-1)];
 67             st = A[hs(i-tmp+1,i+tmp-1)];
 68         }
 69         while(tmp<p)
 70         {
 71             st.a[s[i+tmp]-'a']+= (tmp == 0?1:2);
 72             if(st.ok()) sum++;
 73             num[hs(i-tmp,i+tmp)] = sum;
 74             A[hs(i-tmp,i+tmp)] = st;
 75             tmp++;
 76         }
 77         ans+=sum;
 78         // printf("# %d %lld\n",i,sum);
 79     }
 80 }
 81 void solve_even()
 82 {
 83     A.clear();
 84     num.clear();
 85     for(int i=1; i<L; i++)
 86     {
 87         // printf("### %d\n",i);
 88         int l = 1,r = min(i,L-i)+1;
 89         while(r-l>1)
 90         {
 91             int mid = (l+r)/2;
 92             if(hs(i-mid+1,i+mid)== rhs(i-mid+1,i+mid)) l=mid;
 93             else r=mid;
 94         }
 95         int p=l;
 96         int tmp = p;
 97         while(tmp>=1&&num.find(hs(i-tmp+1,i+tmp))==num.end()) tmp--;
 98         LL sum = 0;
 99         N st;
100         st.clear();
101         // printf("## %d\n",p);
102         if(tmp>=1)
103         {
104             sum=num[hs(i-tmp+1,i+tmp)];
105             st = A[hs(i-tmp+1,i+tmp)];
106         }
107         while(tmp<p)
108         {
109             // printf("# %d %lld\n",tmp,sum);
110             st.a[s[i+tmp+1]-'a']+= 2;
111             if(st.ok()) sum++;
112             num[hs(i-tmp,i+tmp+1)] = sum;
113             A[hs(i-tmp,i+tmp+1)] = st;
114             tmp++;
115         }
116         ans+=sum;
117         // printf("# %d %lld\n",i,sum);
118     }
119 }
120 
121 int main()
122 {
123     freopen("str.in","r",stdin);
124     freopen("str.out","w",stdout);
125     scanf("%s",s+1);
126     L=strlen(s+1);
127     s[0]='#';
128     pw[0]=1;
129     for(int i=1; i<=L; i++) pw[i] = pw[i-1]*13131 ;
130     for(int i=1; i<=L; i++) h[i] = h[i-1]*13131 + s[i];
131     for(int i=L; i>=1; i--) rh[i] = rh[i+1]*13131 + s[i];
132     solve_odd();
133     solve_even();
134     printf("%lld\n",ans);
135     fclose(stdout);
136     return 0;
137 }
AC

 

posted @ 2017-10-09 22:15  Aptal丶  阅读(416)  评论(0编辑  收藏  举报