CI 叠筐
把一个个大小差一圈的筐叠上去,使得从上往下看时,边筐花色交错。这个工作现在要让计算机来完成,得看你的了。
输入
输入是一个个的三元组,分别是,外筐尺寸n(n为满足0<n<80的奇整数),中心花色字符,外筐花色字符,后二者都为ASCII可见字符;
输出
输出叠在一起的筐图案,中心花色与外筐花色字符从内层起交错相叠,多筐相叠时,最外筐的角总是被打磨掉。叠筐与叠筐之间应有一行间隔。
样例输入
5 ^ !
7 ( )
0
样例输出(图形显示错误,应为包围状仿圆形筐形,花纹由内而外按层交错分布)
^^^
^!!!^
^!^!^
^!!!^
^^^
)))))
)((((()
)()))()
)()()()
)()))()
)((((()
)))))
//#include<iostream>
//#include<algorithm>
//#include<cstring>
//#include<cmath>
//using namespace std;
///*
// 用一个缓存数组表示要输出的字符序列。阵列的左上角为(1,1),右下角为(n,n)。由内到外完成排版。
// 最内层的横坐标是(n+1)/2
//然后向上遍历 到1为止
//记 k 为当前位置的横坐标 那么每一行需要打印的字符个数为从 k 到 n-k+1
//*/
//int main(){
// int n = 0;
// int a[81][81];
// char cen,out,cc; //cen:中心字符 out:外围字符,cc:暂存备用字符
// while(scanf("%d %c %c",&n,&cen,&out)!=EOF){
// if(n == 0){
// break;
// }
// int k = (n + 1 ) / 2;//找到最中心的位置
// int count = 0;//计数用,偶数用cen(中心字符)填充(从count从0开始),奇数用外围out填充
// for(int i = k; i >= 1; i--){//横纵坐标均从1 开始
// if(count % 2 == 0){//用count奇偶来判断填充哪个字符
// cc = cen;
// }else{
// cc = out;
// }
// for(int j = i; j <= n - i + 1 ; j++){//n - i + 1为与 i 对称位置的坐标
// a[i][j] = a[n - i + 1][j] = cc; //随j的变化横向→纵列↓填充
// a[j][i] = a[j][n - i + 1] = cc; //随j的变化纵向↓横列→填充
// }
// count++;//计数器记录
// }
// if(n != 1){//不是只有一个筐的情况下,每个角都要被赋值为空格' '
// a[1][1] = a[1][n] = a[n][1] = a[n][n] = ' ';//四个角置空格
// }
// for(int i = 1; i <= n; i++){
// for(int j = 1; j <= n; j++){
// printf("%c",a[i][j]);
// }
// printf("\n");
// }
// printf("\n");
// }
// return 0;
//}
CJ 互质
给你一个正整数n,请问有多少个比n小的且与n互质的正整数?
两个整数互质的意思是,这两个整数没有比1大的公约数。
输入
输入包含多组测试数据。每组输入是一个正整数n(n<=1000000000)。当n=0时,输入结束。
输出
对于每组输入,输出比n小的且与n互质的正整数个数。
样例输入 Copy
7
12
0
样例输出 Copy
6
4
欧拉函数参考自https://www.cnblogs.com/hands...
//#include<iostream>
//#include<algorithm>
//#include<cstring>
//#include<cmath>
//using namespace std;
////typedef long long ll;//可以用typedef将long long名称化简为ll
///*
//质数 = 素数
//φ(x)=x(1-1/p(1))(1-1/p(2))(1-1/p(3))(1-1/p(4))…..(1-1/p(n)) 其中p(1),p(2)…p(n)为x的所有质因数
//两个整数互质的意思是,这两个整数没有比1大的公约数(两个数不必为质数)
//质因数,就是指一个正整数的约数,且必须为质数,也称质因子或质约数,如30的质因数为2,3,5,没6
//*/
//long long Euler(long long x){
// long long res = x;//给res赋初值x,便于后面连乘
// for(long long i = 2; i*i <= x; i++){//不用对2-x全部取余,只需对2-根号x取余
// if(x % i == 0){//i为一个质因子
// res = res / i *(i - 1);//先进行除法防止溢出(ret=ret*(1-1/p(i)))
// while(x % i == 0){//注意此处x仍为传入的数值,并未变化,变化的是res
// x /= i; //将得到的质因子从x中除去,如若30不除去2这个质因数,则30 % 6 == 0,6这个不是其质因数的数也会被计算在res内)
// }
// }
// }
// if(x > 1){//保证我们已经除完了n的所有的质因子,若n > 1有可能还会出现一个我们未除的因子
// res = res / x * (x - 1);//剩下一个未除去的质因子是x自身 ,即1-1/x = (x - 1)/x
// }
// return res;
//}
//int main(){
// long long n = 0;
// while(scanf("%lld",&n)!=EOF,n){
// printf("%lld\n",Euler(n));
// }
// return 0;
//}
CK 赌徒
有n个赌徒打算赌一局。规则是:
每人下一个赌注,赌注为非负整数,且任意两个赌注都不相同。胜者为赌注恰好是其余任意三个人的赌注之和的那个人。如果有多个胜者,我们取赌注最大的那个为最终胜者。
例如,A,B,C,D,E分别下赌注为2、3、5、7、12,最终胜者是E,因为12=2+3+7。
输入
输入包含多组测试数据。每组首先输入一个整数n(1<=n<=1000),表示赌徒的个数。
接下来n行每行输入一个非负整数b(0<=b<32768),表示每个赌徒下的赌注。
当n=0时,输入结束。
输出
对于每组输入,输出最终胜者的赌注,如果没有胜者,则输出no solution。
样例输入 Copy
5
2
3
5
7
12
5
2
16
64
256
1024
0
样例输出 Copy
12
no solution
这个题的测点很迷,基本很水的或者错误的都能通过,下面写一下暴力枚举和二分的做法,尽量把二分当做主解决方案!
//#include<iostream>
//#include<algorithm>
//#include<cstring>
//#include<cmath>
//using namespace std;
///*
//本题暴力+枚举
// 三重循环a[i], a[j], a[k],a[l]分别代表四个人先选一个当前最大的值a[i];
// 然后找一个第二大的a[j]用a[i]减去a[j]和a[k]得到差a[l];
// 如果在剩下的数据中找到a[l]就说明这四个人是符合题中描述的条件的;
// 对于a【i】,找过的就不用再找了,因为我是从大往小找的
// 所以找到的第一个就是赌注最大的那个,之后结束循环输出就可以了。
//*/
//int main(){
// int n = 0,i,j,k,l;
// int a[1001];
// while(scanf("%d",&n) != EOF,n){
// int flag = 0;//标记是否找出了胜者
// for(i = 0; i < n; i++){
// scanf("%d",&a[i]);
// }
// sort(a,a + n);//把筹码升序排列
// for(i = n - 1; i >= 3; i--){
// for(j = i - 1; j >= 2; j--){
// for(k = j - 1; k >= 1; k--){
// for(l = k - 1; l >= 0; l--){
// if(a[i] - a[j] - a[k] == a[l]){
// printf("%d\n",a[i]);
// flag = 1;
// break;//
// }
// }
// if(flag){
// break;
// }
// }
// if(flag){
// break;
// }
// }
// if(flag){
// break;
// }
// }
// if(!flag){
// printf("no solution\n");
// }
// }
// return 0;
//}
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
/*
第二种:暴力+二分枚举
三重循环a[i], a[j], a[k],a[l]分别代表四个人先选一个当前最大的值a[i];
然后找一个第二大的a[j]用a[i]减去a[j]和a[k]得到差a[l];
如果在剩下的数据中找到a[l]就说明这四个人是符合题中描述的条件的;
对于a【i】,找过的就不用再找了,因为我是从大往小找的
所以找到的第一个就是赌注最大的那个,之后结束循环输出就可以了。
*/
//二分查找
int Binary_Search(int a[],int low,int high,int key){
int mid;
while(low <= high){
mid = (low + high) / 2;
//>>是可以看做是除2,如12的二进制zhi表示是00001100,>>1将00001100右移一位,变为00000110,即6
if(key == a[mid]){
return mid;
}else if(key < a[mid]){
high = mid - 1;
}else{
low = mid + 1;
}
}
return -1;
}
int main(){
int n = 0,i,j,k,p,bet,ans;
int a[1001];
while(scanf("%d",&n) != EOF,n){
int flag = 0;//标记是否找出了胜者
for(i = 0; i < n; i++){
scanf("%d",&a[i]);
}
sort(a,a + n);//把筹码升序排列
for(i = n - 1; i >= 0; i--){
for(j = 0; j < i; j++){
for(k = j + 1; k < n; k++){
bet = a[i] - a[j] - a[k];
p = Binary_Search(a,k + 1,n,bet);//j = 0,k = j + 1 = 1,二分查找的位置是a[k]之后的位置k+1开始一直到n
if(p != -1 && p !=i){//p!=i是防止其他值均为0,找到其本身(a[i]-0-0 = a[i])与本身相同
ans = i;
flag = 1;//查找成功,置1
break;
}
}
if(flag){
break;
}
}
if(flag){
break;
}
}
if(!flag){
printf("no solution\n");
}else{
printf("%d\n",a[ans]);
}
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。