蓝桥杯所有专项练习
小明这些天一直在思考这样一个奇怪而有趣的问题:
在 1∼N1∼N 的某个排列中有多少个连号区间呢?
这里所说的连号区间的定义是:
如果区间 [L,R][L,R] 里的所有元素(即此排列的第 LL 个到第 RR 个元素)递增排序后能得到一个长度为 R−L+1R−L+1 的“连续”数列,则称这个区间连号区间。
当 NN 很小的时候,小明可以很快地算出答案,但是当 NN 变大的时候,问题就不是那么简单了,现在小明需要你的帮助。
第一行是一个正整数 NN,表示排列的规模。
第二行是 NN 个不同的数字 PiPi,表示这 NN 个数字的某一排列。
输出一个整数,表示不同连号区间的数目。
1≤N≤100001≤N≤10000,
1≤Pi≤N1≤Pi≤N
4
3 2 4 1
7
5
3 4 2 5 1
9
第一个用例中,有 77 个连号区间分别是:[1,1],[1,2],[1,3],[1,4],[2,2],[3,3],[4,4][1,1],[1,2],[1,3],[1,4],[2,2],[3,3],[4,4]
第二个用例中,有 99 个连号区间分别是:[1,1],[1,2],[1,3],[1,4],[1,5],[2,2],[3,3],[4,4],[5,5]
分析:我们的想法一般就是枚举所有的区间去判断这是否是一个“连号区间”
判断:如果这是一个连号区间,那么就满足最大值和最小值的差就是区间的长度,那么满足差值为区间的长度是否就可以判断它是连号区间呢?可能有这样一组案例
1144
,最大值 - 最小值 == 2(区间长度),但是题目说明了 在 1∼N 的某个排列中有多少个连号区间,这是一个排列,所以不存在重复值,因此由最大最小值差来确定是否是 连号区间的方法是成立的
#include
#include
#include
using namespace std;
const int N = 10010, inf = 1000000000;
int n, a[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
int minx, maxx,fins = 0;
for (int i = 0; i < n; i++) { //区间的左端点
minx = inf, maxx = - inf;
for (int j = i; j < n; j++) { //区间的右端点
//判断maxx - minx是否是区间的长度
minx = min (minx, a[j]); //更新最值
maxx = max (maxx, a[j]);
if (maxx - minx == j - i) fins ++;
}
}
cout << fins;
return 0;
}
给定三个整数数组
A=[A1,A2,…AN]A=[A1,A2,…AN],
B=[B1,B2,…BN]B=[B1,B2,…BN],
C=[C1,C2,…CN]C=[C1,C2,…CN],
请你统计有多少个三元组 (i,j,k)(i,j,k) 满足:
第一行包含一个整数 NN。
第二行包含 NN 个整数 A1,A2,…ANA1,A2,…AN。
第三行包含 NN 个整数 B1,B2,…BNB1,B2,…BN。
第四行包含 NN 个整数 C1,C2,…CNC1,C2,…CN。
一个整数表示答案。
1≤N≤1051≤N≤105,
0≤Ai,Bi,Ci≤1050≤Ai,Bi,Ci≤105
3
1 1 1
2 2 2
3 3 3
27
难度:中等 |
---|
时/空限制:1s / 64MB |
总通过数:4942 |
总尝试数:17100 |
来源:第九届蓝桥杯省赛C++B组,第九届蓝桥杯省赛JAVAB组 |
算法标签 |
1.前缀和思路
思路借鉴于yxc
分析:10^5最多是NlogN,我们枚举b,每一次是计算a中比b[i]小的数乘上c中比b[i]大的数
我们就可以提前计算出来,用cnt[a[i]]记录a[i]出现的次数,用s[]计算出前缀和 -》 s[value]就是比value小的数的个数的和,用来记录比b[i]大的数和比b[i]小的数
#include
#include
#include
#include
using namespace std;
typedef long long LL;
const int N = 100010;
int n;
int a[N], b[N], c[N];
int cnt[N], counta[N], countc[N], s[N];
int main()
{
ios::sync_with_stdio(0);
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i],a[i]++;
for (int i = 0; i < n; i++) cin >> b[i],b[i]++;
for (int i = 0; i < n; i++) cin >> c[i],c[i]++;
//求counta[]
for (int i = 0; i < n; i++) cnt[a[i]] ++; //哈希数组记录a[i]出现了多少次
for (int i = 1; i < N; i++) s[i] = s[i - 1] + cnt[i]; //求cnt[]的前缀和
for (int i = 0; i < n; i++) counta[i] = s[b[i] - 1]; //counta【b[i] - 1】代表比b[i]小的数的个数的和
//求countc[],先把cnt和s数组清零
memset(cnt, 0 ,sizeof cnt);memset(s, 0, sizeof s);
for (int i = 0; i < n; i++) cnt[c[i]] ++;
for (int i = 1; i < N; i++) s[i] = s[i - 1] + cnt[i];
for (int i = 0; i < n; i++) countc[i] = s[N - 1] - s[b[i]]; //全部的个数 - 小于等于b[i] 的个数 = 大于b[i]的个数
LL fins = 0;
for (int i = 0; i < n; ++i ) {
fins += (LL)counta[i] * countc[i];
}
cout << fins;
return 0;
}
2.二分查找
比较正常的思路肯定是二分查找啦,直接上代码,用的是STL自带的lower_bound和upper_bound
如果不太明白的可以参考一下 这一篇文章
注意下面的得到的数是下标,而数组的下标从0开始,因此具体的个数要和下标的值区分好
#include
#include
#include
#include
using namespace std;
const int N = 100010;
int n;
int a[N], b[N], c[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n; i++) cin >> b[i];
for (int i = 0; i < n; i++) cin >> c[i];
sort(a, a + n); sort(b, b + n); sort(c, c + n);
long long fins = 0;
for (int i = 0; i < n; i++) {
long long num1 = lower_bound(a, a + n, b[i]) - a; //第一个大于等于b[i]的数的下标
long long num2 = upper_bound(c, c + n, b[i]) - c; //第一个大于b[i]的数的下标
num2 = n - num2 ;
fins += num1 * num2;
}
cout << fins;
return 0;
}
手写二分,不确定暴力杯是否让使用上面的标准库的源码,保险亿点
#include
#include
#include
#include
using namespace std;
const int N = 100010;
int n;
int a[N], b[N], c[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
for (int i = 0; i < n; i++) cin >> b[i];
for (int i = 0; i < n; i++) cin >> c[i];
sort(a, a + n); sort(b, b + n); sort(c, c + n);
long long fins = 0;
for (int i = 0; i < n; ++i) {
int left = 0, right = n - 1, mid, value = b[i];
while (left < right) {
//找小于b[i]的数的最大的下标
int mid = (left + right + 1) >> 1;
if (a[mid] >= value) {
right = mid - 1;
}else {
left = mid;
}
}
int num1 = left; //确定好了num1
if(a[num1] >= value)
num1 = - 1;
//下面查找大于b[i]的最小的值
left = 0, right = n - 1;
while (left < right ) {
int mid = (left + right) >> 1;
if (c[mid] > value) {
right = mid;
}else left = mid + 1;
}
int num2 = right;
if(c[num2] <= value)
num2 = n;
num2 = n - num2 ;
fins += 1ll * (num1 + 1) * num2;
}
cout << fins;
return 0;
}
小明对数位中含有 2、0、1、92、0、1、9 的数字很感兴趣(不包括前导 00),在 11 到 4040 中这样的数包括 1、2、9、101、2、9、10 至 32、3932、39 和 4040,共 2828 个,他们的和是 574574。
请问,在 11 到 nn 中,所有这样的数的和是多少?
共一行,包含一个整数 nn。
共一行,包含一个整数,表示满足条件的数的和。
1≤n≤100001≤n≤10000
40
574
还是比较符合圈钱杯的题目类型的哇,比较简单的模拟题目,写一个函数判断每一个位是否是匹配2 0 1 9这四个数
#include
#include
#include
#include
using namespace std;
const int N = 100010;
int n;
long long fins;
int judge(int a) {
int value = a;
while (value) {
int x = value % 10;
if (x == 0 || x == 1 || x== 9 || x == 2) return a;
value /= 10;
}
return 0; //全部位数都判断完了,都不匹配,返回0
}
int main()
{
cin >> n ;
for (int i = 1; i <= n; i++) {
fins += judge(i);
}
cout << fins;
return 0;
}
某涉密单位下发了某种票据,并要在年终全部收回。
每张票据有唯一的ID号。
全年所有票据的ID号是连续的,但ID的开始数码是随机选定的。
因为工作人员疏忽,在录入ID号的时候发生了一处错误,造成了某个ID断号,另外一个ID重号。
你的任务是通过编程,找出断号的ID和重号的ID。
假设断号不可能发生在最大和最小号。
第一行包含整数 NN,表示后面共有 NN 行数据。
接下来 NN 行,每行包含空格分开的若干个(不大于100个)正整数(不大于100000),每个整数代表一个ID号。
要求程序输出1行,含两个整数 m,nm,n,用空格分隔。
其中,mm表示断号ID,nn表示重号ID。
1≤N≤1001≤N≤100
2
5 6 8 11 9
10 12 9
7 9
分析:很恶心啊,它输入的时候并不告诉你输入几个数,如果没有接触到stringstream可能会懵掉。或者比较呆呆的直接忽略掉n,剩下的我就直接while(cin…),:)其实这样真的是可以的哈哈,注意不要while (scanf…) scanf读到文件结束符号返回的是-1 ,不是0
那么我们就用stringstream进行一行数据的读取,不了解的可以点击这里和这里
#include
#include
#include
#include
using namespace std;
const int N = 10011;
int number = 0;
int a[N], res1 ,res2;
string t, line;
int main()
{
int n;
cin >> n;
getline(cin, line); //吃掉回车
while (n --) {
getline(cin, line);
stringstream ss(line); //stringstream流,用来读取一整行的字符串,可以将字符串中的空格过滤掉
while (ss >> a[number]) { //将流重定向到t中,每一次以空格为分隔
number++;
}
}
sort(a, a + number);
for (int i = 1; i < number; ++i) {
if (a[i] == a[i - 1]) res2 = a[i - 1]; //重复的值
else if (a[i] - a[i - 1] >= 2) res1 = a[i] - 1; //缺掉的号
}
cout << res1 << ' ' << res2;
return 0;
}
在日常生活中,通过年、月、日这三个要素可以表示出一个唯一确定的日期。
牛牛习惯用 88 位数字表示一个日期,其中,前 44 位代表年份,接下来 22 位代表月份,最后 22 位代表日期。
显然:一个日期只有一种表示方法,而两个不同的日期的表示方法不会相同。
牛牛认为,一个日期是回文的,当且仅当表示这个日期的 88 位数字是回文的。
现在,牛牛想知道:在他指定的两个日期之间(包含这两个日期本身),有多少个真实存在的日期是回文的。
一个 88 位数字是回文的,当且仅当对于所有的 ii(1≤i≤81≤i≤8) 从左向右数的第 ii 个数字和第 9−i9−i 个数字(即从右向左数的第 ii 个数字)是相同的。
例如:
输入包括两行,每行包括一个 88 位数字。
第一行表示牛牛指定的起始日期 date1date1,第二行表示牛牛指定的终止日期 date2date2。保证 date1date1 和 date2date2 都是真实存在的日期,且年份部分一定为 44 位数字,且首位数字不为 00。
保证 date1date1 一定不晚于 date2date2。
输出共一行,包含一个整数,表示在 date1date1 和 date2date2 之间,有多少个日期是回文的。
20110101
20111231
1
分析:给了起始时间和末尾时间我们可能想到的一种方法就是,枚举所有的日期,并且判断是否是回文日期。但是对于日期的表示很麻烦,比如说你的1月应该表示为01。那我们不妨枚举所有的回文日期,判断它能否表示为一个日期,因为回文串是对称的,因此我们枚举四位就行了
#include
#include
#include
using namespace std;
const int N = 10010;
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int data1, data2;
int fins;
bool judge(int x) { //传进来的都是回文串,判断这个是否是符合日期的
int year = x / 10000;
int month = x % 10000 / 100;
int day = x % 100;
if (month <= 0 || month > 12) return false; //先不考虑二月的情况
if (day <= 0 || (month != 2 && day > days[month]))return false ;
int leap = year % 100 && year % 4 == 0 || year % 400 == 0;
if (month == 2) {
if (day > 28 + leap)return false;
}
return true;
}
int main()
{
cin >> data1 >> data2;
//枚举回文串
for (int i = 1000; i <= 9999; i++) {
int data = i, t = i;
//构造成为回文串
for (int j = 0; j < 4; j++) data = data * 10 + t % 10, t /= 10;
if (data1 <= data && data <= data2 && judge(data)) fins ++;
}
cout << fins;
return 0;
}
给定你一个长度为 nn 的整数数列。
请你使用归并排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入共两行,第一行包含整数 nn。
第二行包含 nn 个整数(所有整数均在 1∼1091∼109 范围内),表示整个数列。
输出共一行,包含 nn 个整数,表示排好序的数列。
1≤n≤1000001≤n≤100000
5
3 1 2 4 5
1 2 3 4 5
不明白原理的可以百度或者点击这里
下面的代码比邓俊辉老师的弱一点,但是我觉得更好理解,大家请自取
#include
#include
#include
#include
using namespace std;
const int N = 100010;
int n, a[N];
void merge(int *a, int start, int mid, int end) {
int *tmp = new int[end - start + 1]; //开辟与数组同大小的暂存区,也可以开辟的[low,mid]
int i = start; //C数组
int j = mid + 1; //B数组
int k = 0; //A数组
while (i <= mid && j <= end) {
//谁小就填充
tmp[k++] = (a[i] <= a[j]) ? a[i++] : a[j++];
}
while (i <= mid) tmp[k++] = a[i++];
while (j <= end) tmp[k++] = a[j++];
//将数组返回到a中
for (int i = 0; i < k; i++) {
a[start + i] = tmp[i];
}
delete [] tmp;
}
void mergeSort(int *a, int start, int end) {
if (a == NULL || start >= end) return ;
int mid = (end + start) >> 1;
mergeSort(a, start, mid);
mergeSort(a, mid + 1, end);
merge(a, start, mid, end);
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> a[i];
mergeSort(a, 0, n - 1); // 归并排序
for (int i = 0; i < n; ++i ) cout << a[i] << " ";
return 0;
}
X星球居民小区的楼房全是一样的,并且按矩阵样式排列。
其楼房的编号为 1,2,3…1,2,3…
当排满一行时,从下一行相邻的楼往反方向排号。
比如:当小区排号宽度为 66 时,开始情形如下:
1 2 3 4 5 6
12 11 10 9 8 7
13 14 15 .....
我们的问题是:已知了两个楼号 mm 和 nn,需要求出它们之间的最短移动距离(不能斜线方向移动)。
输入共一行,包含三个整数 w,m,nw,m,n,ww 为排号宽度,m,nm,n 为待计算的楼号。
输出一个整数,表示 m,nm,n 两楼间最短移动距离。
1≤w,m,n≤100001≤w,m,n≤10000,
6 8 2
4
分析:确定num1,num2的行号列号进行绝对值相减就行了
行号:数值不是从0开始而是从1开始进行排列的,那我们的行号就是(num - 1) / height 行号会出现0,列号是从1开始的,我们求的是差值,就不要在意是否和矩阵中的行列是否匹配了
列号:行号是偶数的话就是从左向右排列,直接取模,特判模为0
行号是奇数的话就用height减一下就是了
#include
#include
#include
#include
using namespace std;
const int N = 10010;
int height, num1, num2;
int main()
{
cin >> height >> num1 >> num2;
//就是求出来num1和num2的行号和列号
int r1, r2, c1, c2;
r1 = (num1 - 1) / height; r2 = (num2 - 1) / height;
if (r1 % 2 == 0) {
c1 = num1 % height;
c1 = (c1 == 0) ? height : c1;
}else {
c1 = height - (num1 % height) + 1;
}
if (r2 % 2 == 0) {
c2 = num2 % height;
c2 = (c2 == 0) ? height : c2;
}else {
c2 = height - (num2 % height) + 1;
}
//cout << r1 << " " << r2 << " " << c1 << " " << c2 << endl;
int fins = abs(r1 - r2) + abs(c1 - c2);
cout << fins;
return 0;
}
小明正在整理一批历史文献。这些历史文献中出现了很多日期。
小明知道这些日期都在1960年1月1日至2059年12月31日。
令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。
更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。
比如02/03/04,可能是2002年03月04日、2004年02月03日或2004年03月02日。
给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?
一个日期,格式是”AA/BB/CC”。
即每个’/’隔开的部分由两个 0-9 之间的数字(不一定相同)组成。
输出若干个不相同的日期,每个日期一行,格式是”yyyy-MM-dd”。
多个日期按从早到晚排列。
0≤A,B,C≤90≤A,B,C≤9
02/03/04
2002-03-04
2004-02-03
2004-03-02
同上面的日期回文串的问题类似,我们可以枚举所有的数,判断是不是一个日期,如果是日期的话看一下是否能够写成输入的格式,这样的好处是不用处理升序的格式和重复的问题了
#include
#include
#include
#include
using namespace std;
const int N = 100010;
int days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int a, b, c;
bool judge(int year, int month, int day){
//年份肯定是可以的
if (month == 0 || month > 12) return false;
if (day == 0 || (month != 2 && day > days[month])) return false;
if (month == 2) {
int leap = (year % 100 && year % 4 == 0) || year % 400 == 0; //闰年为1,不是闰年为0
if (day > 28 + leap) return false;
}
return true;
}
int main()
{
scanf ("%d/%d/%d", &a, &b, &c); //用scanf进行输入的格式控制
for (int i = 19600101; i <= 20591231; ++i) {
//判断所有的数是不是正确的日期
//判断对应的日期是不是能够表示成为输入的个数
int year = i / 10000; int month = i % 10000 / 100; int day = i % 100;
if (judge(year, month, day))
{
if (year % 100 == a && month == b && day == c || // 年/月/日
month == a && day == b && year % 100 == c || // 月/日/年
day == a && month == b &&year % 100 == c) // 日/月/年
printf("%d-%02d-%02d\n", year, month, day);
}
}
}
题目背景
在absi2011的帮派里,死号偏多。现在absi2011和帮主等人联合决定,要清除一些死号,加进一些新号,同时还要鼓励帮贡多的人,对帮派进行一番休整。
题目描述
目前帮派内共最多有一位帮主,两位副帮主,两位护法,四位长老,七位堂主,二十五名精英,帮众若干。
现在absi2011要对帮派内几乎所有人的职位全部调整一番。他发现这是个很难的事情。于是要求你帮他调整。
他给你每个人的以下数据:
他的名字(长度不会超过30),他的原来职位,他的帮贡,他的等级。
他要给帮贡最多的护法的职位,其次长老,以此类推。
可是,乐斗的显示并不按帮贡排序而按职位和等级排序。
他要你求出最后乐斗显示的列表(在他调整过职位后):职位第一关键字,等级第二关键字。
注意:absi2011无权调整帮主、副帮主的职位,包括他自己的(这不是废话么…)
他按原来的顺序给你(所以,等级相同的,原来靠前的现在也要靠前,因为经验高低的原因,但此处为了简单点省去经验。)
输入格式
第一行一个数n,表示星月家园内帮友的人数。
下面n行每行两个字符串两个整数,表示每个人的名字、职位、帮贡、等级。
输出格式
一共输出n行,每行包括排序后乐斗显示的名字、职位、等级。
输入输出样例
输入 #1复制
9
DrangonflyKang BangZhu 100000 66
RenZaiJiangHu FuBangZhu 80000 60
absi2011 FuBangZhu 90000 60
BingQiLingDeYanLei HuFa 89000 58
Lcey HuFa 30000 49
BangYou3 ZhangLao 1000 1
BangYou1 TangZhu 100 40
BangYou2 JingYing 40000 10
BangYou4 BangZhong 400 1
输出 #1复制
DrangonflyKang BangZhu 66
RenZaiJiangHu FuBangZhu 60
absi2011 FuBangZhu 60
BingQiLingDeYanLei HuFa 58
BangYou2 HuFa 10
Lcey ZhangLao 49
BangYou1 ZhangLao 40
BangYou3 ZhangLao 1
BangYou4 ZhangLao 1
说明/提示
各种职位用汉语拼音代替。
如果职位剩1个,而有2个帮贡相同的人,则选择原来在前的现在当选此职位。
另: 帮派名号:星月家园
帮主尊号:Dragonfly Kang
帮派ID:2685023
帮派等级:4
帮派人数:101/110
帮派技能:
星月家园资料,欢迎各位豆油加入_
【数据范围】
对于10%的数据,保证n=3
对于40%的数据,保证各个人的帮贡均为0
对于100%的数据,保证3<=n<=110,各个名字长度<=30,0<=各个人的帮贡<=1000000000
1<=各个人等级<=150
保证职位必定为BangZhu,FuBangZhu,HuFa,ZhangLao,TangZhu,JingYing,BangZhong之间一个
保证有一名帮主,保证有两名副帮主,保证有一名副帮主叫absi2011
不保证一开始帮派里所有职位都是满人的,但排序后分配职务请先分配高级职位。例如原来设一名护法现在设两名。
保证名字不重复。
【题目来源】
fight.pet.qq.com
absi2011授权题目
#include
#include
using namespace std;
struct Node{
string name;
string zhiwei1,zhiwei2; //换之前的职位和换之后的职位
int banggong;
int dengji;
int shunxu; //输入的顺序
int zhi; //代表转换后职位对应的数字
};
Node node[120];
bool cmp1(Node a,Node b) //第一次排序 帮贡相同 顺序小的优先
{
if(a.banggong==b.banggong)
return a.shunxu<b.shunxu;
else return a.banggong>b.banggong;
}
bool cmp2(Node a,Node b) //第二次排序 职位优先 然后是等级 然后是顺序
{
if(a.zhi==b.zhi)
{
if(a.dengji==b.dengji)
{
return a.shunxu<b.shunxu;
}
return a.dengji>b.dengji;
}
return a.zhi<b.zhi;
}
int main()
{
int n,count2=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>node[i].name>>node[i].zhiwei1>>node[i].banggong>>node[i].dengji;
node[i].shunxu=i;
}
sort(node+4,node+n+1,cmp1); //由于不能改变帮主 副帮主 所以从第四个开始排序
node[1].zhiwei2=node[1].zhiwei1;
node[2].zhiwei2=node[2].zhiwei1; //帮主和副帮主职位不变
node[3].zhiwei2=node[3].zhiwei1;
for(int i=4;i<=n;i++)
{
if(i==4||i==5)
node[i].zhiwei2="HuFa";
else if(i>=6&&i<=9)
node[i].zhiwei2="ZhangLao";
else if(i>=10&&i<=16)
node[i].zhiwei2="TangZhu";
else if(i>=17&&i<=41)
node[i].zhiwei2="JingYing";
else node[i].zhiwei2="BangZhong";
}
for(int i=1;i<=n;i++)
{
if(node[i].zhiwei2=="BangZhu")
node[i].zhi=0;
else if(node[i].zhiwei2=="FuBangZhu")
node[i].zhi=1;
else if(node[i].zhiwei2=="HuFa")
node[i].zhi=2;
else if(node[i].zhiwei2=="ZhangLao")
node[i].zhi=3;
else if(node[i].zhiwei2=="TangZhu")
node[i].zhi=4;
else if(node[i].zhiwei2=="JingYing")
node[i].zhi=5;
else if(node[i].zhiwei2=="BangZhong")
node[i].zhi=6;
}
sort(node+1,node+1+n,cmp2);
for(int i=1;i<=n;i++)
{
cout<<node[i].name<<" "<<node[i].zhiwei2<<" "<<node[i].dengji<<endl;
}
}
以后会对于模拟排序题目进行补充的,最后希望大家在蓝桥杯都能够取得好的成绩!