L1-002 打印沙漏:
https://pintia.cn/problem-sets/994805046380707840/problems/994805145370476544
解读1:
本题首先结构大致是一个等差数列 *2 再减去多余的只有一个字符的那一列
即每一组的字符总数为 2Sn-1
解读2:
做这道题时陷入了一个思维陷阱里,首先我们每一层最后的两格空格不用考虑 直接回车即可
其次是直接打印即可 不需要把值存到二维数组中
最后是 前面每一层的空格数跟该层层数是有关系的 字符数也是与层数有关
假如一共是3层
***** 第一层 空格数0
*** 第二次 空格数1
* 第三层 空格数2
***
*****
#include
#include
using namespace std;
int main(){
int a[25]={0};
for(int i=1;i<25;i++){
a[i]=2*i*i-1; //见解读1
}
for(int j=1;j<24;j++) cout<<a[j]<<" ";
cout<<endl;
int n;//n<=1000
char c;
scanf("%d %c",&n,&c);
int les;
int h;
for(int i=1;i<25;i++){
if(n-a[i]<0){
les=n-a[i-1];//多余的字符数
h=i-1;//层数
break;
}
}
//打印 细节见解读2
for(int i=1;i<=h;i++){
for(int j=1;j<i;j++){
printf(" ");
}
for(int k=1;k<=2*h+1-2*i;k++){
printf("%c",c);
}
printf("\n");
}
for(int i=1;i<=h-1;i++){
for(int j=1;j<h-i;j++){
printf(" ");
}
for(int k=1;k<=2*i+1;k++){
printf("%c",c);
}
printf("\n");
}
printf("%d\n",les);
return 0;
}
L1-003 个位数统计
https://pintia.cn/problem-sets/994805046380707840/problems/994805143738892288
这道题比较简单
注意点:
1、如果存在字符数组里,记得给字符数组所有空间的值改为一个不是个位数字的符号
L1-005 考试座位号
回顾一下字符数组的输入方式
https://blog.csdn.net/a834352982/article/details/56841873
还碰到了一个问题就是我用字符数组 gets()方法在PAT中不支持 显示未定义
则改为cin.getline(s,n)的形式
再测试发现有两个测试点错误
这道题我想的字符数组存
字符数组方法:https://blog.csdn.net/sunshineacm/article/details/79451730
还可以是结构体。。。
L1-006 连续因子
https://pintia.cn/problem-sets/994805046380707840/problems/994805138600869888
这道题在题意理解上要格外注意
又是一道乘法的数学问题!(每次栽在数学问题上)
涉及到 素数 余数
作者:18Temp 来源:CSDN 原文:https://blog.csdn.net/qq_37729102/article/details/80712640
版权声明:本文为博主原创文章,转载请附上博文链接!从1乘到N,每乘一次判定当前乘积prd是否为N的因子,即N%prd是否为0,若为0,比较上一次乘积因子序列的长度,若大于,则记录。
不断更新乘积因子序列长度,直到最后一个因子为N。当然,最需要注意的是最外层的循环变量i判定条件必须为i<=sqrt(n),如果是i*i<=n,则最后一个测试点会不过。本人猜测可能是平台的问题。虽然看上去很暴力,但此算法最后一个测试点耗时仅5ms
#include
#include
using namespace std;
typedef long long ll;
int main()
{
ll n;
cin>>n;
ll prd=0;//定义乘积
int start=0,len=0;//定义最终得到序列开始的因子,序列的长度
for(int i=2;i<=sqrt(n);i++)//i从2到根号n
{
prd=1;
for(int j=i;prd*j<=n;j++)//从j开始一直乘到N为止,每次乘积判定是否小于等于N,若超过N,则结束循环
{
prd*=j;//乘积迭代
if(n%prd==0&&j-i+1>len)//如果当前乘积为N的乘积因子且长度大于上一次
{//更新序列起始因子和长度
start=i;
len=j-i+1;
}
}
}
if(start==0)//若起始因子为0,说明N为质数,因为质数=1*本身,而循环最多能表示1*本身的根号
{
start=n;
len=1;
}
cout<<len<<'\n'<<start;
for(int i=start+1;i<start+len;i++)//输出,如果因子只有一个只输出一个
cout<<'*'<<i;
return 0;
}
由此,我发现我把题意弄错了 以为是输出最大序列长度和输出最小长度序列的值(傻了 。。最小序列不就是它自己嘛
L1-007 念数字
被0坑了啊 一定要注意特殊情况 还有格式要严格遵循!尤其是空格 坑死我了
#include
#include
using namespace std;
int main()
{
char a[11][5] ={{"ling"},{"yi"},{"er"},{"san"},{"si"},{"wu"},{"liu"},{"qi"},{"ba"},{"jiu"}};
int b;
cin>>b;
int num[1001]; int z=0;
if(b==0){cout<<"ling"; } //0
if(b<0){b*=-1;cout<<"fu ";}//负数时转化成正数并输出fu
while(b)
{
num[z]=b%10;
b/=10;
z++;
}
//b=1234时 num[..]=4321;
for(int j=z-1;j>=0;j--)
{
if(j==0)cout<<a[num[j]];
else cout<<a[num[j]]<<" ";
//对于格式的详细分化
}
return 0;
}
L1-008 求整数段和
一道很简单的题做了很久。。。里面有很多坑。
首先求和没什么问题。
感觉到c语言比c++便利很多啊
总结:好好学C
#include
int main()
{
int a,b,i,cot=0,sum=0;//添加计数器
scanf("%d %d",&a,&b);//输入区间
//以a为起点,如果a小于b,每次a累加1
for(i=a;i<=b;i++){
printf("%5d",i);//题目要求占5个字符宽
cot++;//每输出一次,计数器累加1
if(cot%5==0&&i!=b)//如果当前计数器的值能被5整除那么换行 注意不要多输出一个回车了
printf("\n");
}
printf("\n");//执行完循环后,换行输入总和
for(i=a;i<=b;i++)
sum+=i;
printf("Sum = %d",sum);
return 0;
}
L1-009 N个数求和
注意认真看题目:负数的符号一定出现在分子前面
这个题有几种情况
1、首先判断分子是不是0,如果是的话说明最终结果是0
2、还有最大公约数 最基本的算法问题
也就是辗转相除法 gcd(a,b) = gcd(b,a mod b)。直至余数=0 最大公约数则为M
int Gcd(unsigned int M,unsigned int N)
{
unsigned int Rem;
while(N > 0)
{
Rem = M % N;
M = N;
N = Rem;
}
return M;
}
3、if(n==0) printf(“0\n”);
https://blog.csdn.net/qq_37729102/article/details/80713906
L1-011 A-B
我想的很麻烦 写的也不对 难受。。。
以下是大神代码 思路很清晰 ——数组一一对应 类似映射的方法
#include
#include
#include
int main()
{
char a[10001];
char b[10001];
int c[128];
int i;
gets(a);
gets(b);
for(i=0;i<128;i++)
{
c[i]=0;
}
for(i=0;i<strlen(b);i++)
{
c[(int)b[i]]=1;
}
for(i=0;i<strlen(a);i++)
{
if(c[(int)a[i]]==0)
printf("%c",a[i]);
}
printf("\n");
return 0;
}
L1-012 计算指数
很简单 注意类型的定义。。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
int main()
{
long long n;
cin>>n;
cout<<2<<'^'<<n<<" = "<<pow(2,n)<<endl;
return 0;
}
L1-015 跟奥巴马一起画方块
简单。。判断n是不是奇数 如果是 列数等于n++/2
L1-016 查验身份证
有一个坑是定义char a[ ][ ]时
用scanf("%s",a[i]);输入每一行时最后都会加入一个换行符进去 所以要多留一个空 否则会出现很奇怪的错
还要注意向char数组和int数组放入数字 再取出来是不一样的
char数组取出来转变成int还需要减去’0’
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
int n;
cin>>n;
char a[n][19];//存放身份证
int q[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};//权值
char z[11] = {'1','0','X','9','8','7','6','5','4','3','2'};//对应校验码
int s[100]={0};//标志 如果有问题的就为1 将为1的输出
int flag=0;//如果没有有问题的身份证 就输出all pass
for(int i=0;i<n;i++)
{
scanf("%s",a[i]);
int sum=0;
for(int j=0;j<17;j++)
{
int t;
t=(int)a[i][j]-'0';
if(t<0||t>9){s[i]=1;sum=0;break;} //为字母时
sum+=(t*q[j]);
//cout<
}
if(sum){
sum%=11;
if(z[sum]!=a[i][17])s[i]=1;
}//有问题
}
for(int k=0;k<n;k++)
{
if(s[k]){printf("%s\n",a[k]);flag=1;}//并不是全没问题
}
if(!flag)cout<<"All passed"<<endl;//全没问题时输出
return 0;
}
L1-017 到底有多二
用C语言方式使字符数组可以一次性输入一整行
scanf("%s",a); //a[i] i为行数
#include
#include
#include
#include
using namespace std;
int main(){
string s;
int len,m=0;//长度 ,2的个数
double i=1.0;//程度
cin>>s;
if(s[0]=='-')
i=i*1.5;//注意是*不是+0.5
len=s.size();
// cout<
if((s[len-1]-48)%2==0)
i=i*2;
for(int j=0;j<len;j++){
if(s[j]=='2'){
m++;
}
}
if(s[0]=='-')
len--;
//cout<
double w=(double)((double)m/len)*i*100;
printf("%.2lf%%\n",w);
return 0;
}
佛了 写了多少遍 按照别人的代码一个个对还是有问题
注意 1、char里面的数字和int 里的数字是不一样的!
2、倍数是要乘起来的
3、相乘 数据类型注意一致
L1-018 大笨钟
很简单 一次过。。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
void c (int n){
for(int i=0;i<n;i++)
cout<<"Dang";
cout<<endl;
}
int main()
{
int h;
cin>>h;
getchar();
int t;
cin>>t;
int time[4]={0};
if(h>10){
time[0]=h/10;
time[1]=h%10;
}
else time[1]=h;
if(t>10){
time[2]=t/10;
time[3]=t%10;
}
else time[3]=t;
if(h>=0&&h<=12)cout<<"Only "<<time[0]<<time[1]<<":"<<time[2]<<time[3]<<". Too early to Dang."<<endl;
else if(t>0)c(h+1-12);
else c(h-12);
return 0;
}
L1-019 谁先倒
一开始被数组开小坑了,显示“段错误”,改大之后就可以了
很简单。。。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
int aj,bj; int asum=0,bsum=0;
cin>>aj>>bj;
int n;
cin>>n;
int a[200],b[200];
for(int i=0;i<2*n;i+=2)
{
cin>>a[i]>>a[i+1];
cin>>b[i]>>b[i+1];
int sum=a[i]+b[i];
if(aj>=0&&bj>=0){
if(a[i+1]!=sum&&b[i+1]!=sum)continue;
else if(a[i+1]==sum&&b[i+1]==sum)continue;
else {
if(a[i+1]==sum) {
aj--;asum++;
}
else {
bj--;bsum++;
}
}
}
}
if(aj<0){cout<<'A'<<endl;cout<<bsum<<endl;
}
else {cout<<'B'<<endl;cout<<asum<<endl;
}
return 0;
}
L1-020 帅到没朋友
我想的思路实现起来好麻烦。。。
看一下别人的代码
#include
int main()
{
int Person[100000]={0};
int N,n,m,K,i,j,sum=0;
scanf("%d",&N);
for(i=1;i<=N;i++)
{
scanf("%d",&n);
for(j=1;j<=n;j++)
{
scanf("%d",&m);
if(n!=1) //=1肯定没朋友
Person[m]+=n; //用数组标记即可
}
}
scanf("%d",&K);
for(i=1;i<=K;i++)
{
scanf("%d",&m);
if(Person[m]==0)
{
if(sum!=0)
printf(" "); //没有全输出完时都要输出空格 用于隔开
printf("%05d",m);
//避免多次被检测
Person[m]=-1;
sum++; //有没朋友的人
}
}
if(sum==0) //都有朋友时sum==0
printf("No one is handsome");
printf("\n");
return 0;
}
L1-023 输出GPLT
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
int n[4]={0};
char c;
while((c=getchar())!='\n'){ //注意这个是使getchar结束符为换行
if(c=='g'||c=='G') n[0]++;
else if(c=='p'||c=='P') n[1]++;
else if(c=='l'||c=='L') n[2]++;
else if(c=='t'||c=='T') n[3]++;
else continue;
}
int sum=n[0]+n[1]+n[2]+n[3];
for(;sum;)
{ sum=n[0]+n[1]+n[2]+n[3];
if(n[0]){
cout<<"G";
n[0]--;
}
if(n[1]){
cout<<"P";
n[1]--;
}
if(n[2]){
cout<<"L";
n[2]--;
}
if(n[3])
{
cout<<"T";
n[3]--;
}
}
cout<<endl;
return 0;
}
L1-025 正整数A+B
这道题有一个坑是A可以是一个空串 并且 b可以是一个空格组成的串
所以我们定义的string b 输入方式改成getline(cin,b); 就可以输入空格串啦
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int f(string a){
for(int i=0;i<a.length();i++)
{
if(a[i]<48||a[i]>57)return 0;
}
return 1;
}
int s(string a){
int sum=0;
int k=1;
for(int j=a.length()-1;j>=0;j--)
{
int xs=0;
xs+=(int)a[j];
xs-=48;
xs*=k;
sum+=xs;
k*=10;
}
return sum;
}
int main()
{
string a,b;
a="";
int absum=0;
char c;
c=getchar();
while(c!=' '&&c!='\n'){
a+=c;
c=getchar();
}
getline(cin,b);
if(f(a)==0)a="?";
if(f(b)==0)b="?";
if(s(a)>1000||s(a)<1) a="?";
if(s(b)>1000||s(b)<1) b="?";
if(a!="?"&&b!="?"){
absum=s(a)+s(b);
cout<<a<<" + "<<b<<" = ";
cout<<absum<<endl;
}
else {
cout<<a<<" + "<<b<<" = ?";
}
return 0;
}
L1-027 出租
实现上有点麻烦,其他没什么问题
#include
#include
#include
#include
#include
#include
#include
using namespace std;
bool compare (int a,int b)
{
return a>b;
}
int main()
{
char p[11];
int arr[11]={0};
char farr[11];
int sum=0;int dsum=0;
scanf("%s",p);
for(int i=0;i<=10;i++)
{ int c=(int)p[i]-'0';
if(arr[c]==0) {
arr[c]=1;
farr[sum]=p[i];
sum++;
}
}
dsum=sum;
sort(farr,farr+sum,compare);
cout<<"int[] arr = new int[]{";
for(int z=10;z>=0;z--)
{
if(arr[z]==1){
cout<<z;
dsum--;
}
else continue;
if(dsum)cout<<",";
}
cout<<"};"<<endl;
cout<<"int[] index = new int[]{";
for(int q=0;q<11;q++)
{
int pp=0;
while(p[q]!=farr[pp])pp++;
cout<<pp;
if(q!=10)cout<<',';
}
cout<<"};"<<endl;
return 0;
}
L1-030 一帮一
实现上用了很长时间,还需要锻炼
#include
#include
#include
#include
#include
#include
#include
using namespace std;
struct person{
bool sex;
string name;
bool h;
};
int main()
{
int n;
cin>>n;
person p[n];
for(int i=0;i>p[i].sex;
cin>>p[i].name;
p[i].h=1;//未分配
}
int sum=n;
int j=0;
for(int k=n-1;k>0&∑k--)
{
if(p[j].sex!=p[k].sex&&p[j].h&&p[k].h){
cout<
L1-032 Left-pad
想复杂了 直接输出就可以 之前还在想怎么把数组里面处理成结果的样子呜呜
这啥意思???
%d 整型
%* 忽略
%c 带表示忽略 就是说,在输入流中,读取一个字符
scanf("%[^\n]%*c",str)
表示读入一行字符串。
^ 表示"非",[^\n]表示读入换行字符就结束读入。
L1-033 出生年
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int num(int y)
{
int k=0;
int sum[10]={0};
int a=y%10;
int b=y%100/10;
int c=y%1000/100;
int d=y/1000;
sum[a]++;
sum[b]++;
sum[c]++;
sum[d]++;
//cout<
//cout<
for(int i=0;i<10;i++)
{
if(sum[i])k++;
}
return k;
}
int main()
{
int y,n,year;
cin>>y>>n;
year=y;
for(;year<4000;year++){
if(num(year)==n){
if(year<10){
cout<<year-y<<" 000"<<year<<endl;
break;
}
else if(year<100){
cout<<year-y<<" 00"<<year<<endl;
break;
}
else if(year<1000){
cout<<year-y<<" 0"<<year<<endl;
break;
}
else {
cout<<year-y<<" "<<year<<endl;
break;
}
}
}
return 0;
}