蛇形填数
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int n;
int a[1000][1000];
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n;
int tot = 0;
memset(a, 0, sizeof(a));
int x =0, y = n-1;
x =0;
a[0][n-1] =1;
tot = 1;
while(tot < n*n)
{
while(x+1<n && !a[x+1][y]) a[++x][y] =++tot;
while(y-1>=0 && !a[x][y-1]) a[x][--y] = ++tot;
while(x-1>=0 && !a[x-1][y]) a[--x][y] = ++tot;
while(y+1< n && !a[x][y+1]) a[x][++y] = ++tot;
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
return 0;
}9
环状序列 Uva 1584
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int les(const char *s, int p,int q)
{
int n = strlen(s);
for(int i = 0; i<n; i++)
{
if(s[(p + i) % n] != s[(q + i) % n])
return s[(p + i) % n] < s[(q + i) % n];
}
return 0;
}
int main()
{
int t;
char s[100];
scanf("%d", &t);
while(t--)
{
scanf("%s", s);
int ans = 0;
int n = strlen(s);
for(int i = 1; i<n; i++)
if(les(s, i, ans)) ans = i;
for(int i = 0; i<n; i++)
putchar(s[(i+ans) % n]);
cout<<endl;
}
return 0;
}
总结
这道题的循环用得非常好,取余这个操作也非常好。
得分 Score Uva 1585
总结:基础循环的应用。
#include<iostream>
#include<cstring>
using namespace std;
int len;
int main()
{
int T;
cin>>T;
while(T--)
{
char s[100];
int vis[100];
memset(vis, 0, sizeof(vis));
scanf("%s",s);
len = strlen(s);
int sum = 0;
int flag = 0;
for(int i = 0; i < len; i++)
{
if(s[i] == 'X')
{
flag = 0;
}
else
{
flag ++;
sum += flag;
}
}
cout<<sum<<endl;
}
return 0;
}
分子量 Molar Mass Uva 1586
总结:这道题有点小麻烦,要看原子后面的个数有多少个,好的是这道题没括号。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char s[100010];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(s, -1, sizeof(s));
scanf("%s", s);
double sum = 0;
double tp;
for(int i = 0; s[i] != -1; i++)
{
if(s[i] == 'C')
{
tp = 12.01;
int cnt = 0;
while(s[i+1] >='0' && s[i+1] <= '9')
{
cnt = cnt*10+s[i+1]-'0';
i++;
}
if(cnt == 0)
{
sum += tp;
}
else sum += tp *cnt;
}
else if(s[i] == 'H')
{
tp = 1.008;
int cnt = 0;
while(s[i+1] >='0' && s[i+1] <= '9')
{
cnt = cnt*10+s[i+1]-'0';
i++;
}
if(cnt == 0)
{
sum += tp;
}
else sum += tp *cnt;
}
else if(s[i] == 'O')
{
tp = 16.00;
int cnt = 0;
while(s[i+1] >='0' && s[i+1] <= '9')
{
cnt = cnt*10+s[i+1]-'0';
i++;
}
if(cnt == 0)
{
sum += tp;
}
else sum += tp *cnt;
}
else if(s[i] == 'N')
{
tp = 14.01;
int cnt = 0;
while(s[i+1] >='0' && s[i+1] <= '9')
{
cnt = cnt*10+s[i+1]-'0';
i++;
}
if(cnt == 0)
{
sum += tp;
}
else sum += tp *cnt;
}
}
printf("%.3f\n", sum);
}
return 0;
}
数数字 Digit Counting Uva 1225
总结:这道题搞一个vis数组就行。
#include<iostream>
#include<cstring>
using namespace std;
int s[15];
int main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
memset(s, 0, sizeof(s));
for(int i = 1; i <= n; i++)
{
int tp = i;
while(tp)
{
s[tp % 10]++;
tp /= 10;
}
}
for(int i = 0; i<=9; i++)
{
if(i)
cout<<" "<<s[i];
else
cout<<s[i];
}
cout<<endl;
}
return 0;
}
周期串 Periodic Strings Uva 455
总结:这道题用kmp的nex数组来进行操作就好,不知道kmp有什么用处的可以到我的另一篇博客中查看。
kmp超详细题单以及用法
#include <cstdio>
#include<iostream>
#include <cstring>
using namespace std;
int n;
char str[100];
int nxt[100];
int len;
void getNext()
{
int i = 0, j = -1;
nxt[0] = -1;
while (i != len){
if (j == -1 || str[i] == str[j]){
nxt[++i] = ++j;
}
else
j = nxt[j];
}
}
int main()
{
scanf("%d", &n);
while (n--){
scanf("%s", str);
len = strlen(str);
getNext();
if (len % (len - nxt[len]) == 0)
printf("%d\n", len - nxt[len]);
else
printf("%d\n", len);
if (n)
printf("\n");
}
return 0;
}
纵横字谜的答案 Crossword Answers Uva 232
总结:这道题要注意看题,注意一开始要把数组处理好。
#include<iostream>
#include<cstring>
using namespace std;
char a[100][100];
int vis[100][100];
int lrow, lcolumn;
int main()
{
int flag = 0;
while(cin>>lrow && lrow)
{
cin>>lcolumn;
for(int i = 0; i < lrow; i++)
for(int j = 0; j < lcolumn; j++)
cin>>a[i][j];
memset(vis, 0 , sizeof(vis));
int c = 0;
for(int i = 0; i< lrow;i++)
{
for(int j = 0; j < lcolumn; j++)
{
if(i == 0 && a[i][j] != '*')
{
c++;
vis[i][j] = c;
}
else
{
if(j == 0 && a[i][j] != '*')
vis[i][j] = ++c;
else if(a[i][j] != '*' && a[i][j-1] == '*')
vis[i][j] = ++c;
else if(a[i][j] != '*' && a[i-1][j] == '*')
vis[i][j] = ++c;
}
}
}
if(flag )
cout<<"\n";
cout<<"puzzle #"<<++flag<<":\n";
int tp = 0;
cout<<"Across"<<endl;
for(int i = 0; i< lrow; i++)
{
for(int j = 0; j < lcolumn; j++)
{
if(tp == 0 && a[i][j] !='*')
{
printf("%3d.", vis[i][j]);
cout<<a[i][j];
tp =1;
}
else if(a[i][j] == '*' && tp == 1)
{
tp = 0;
cout<<endl;
}
else if(tp == 0 && a[i][j] =='*')
{
continue;
}
else if(tp == 1 && a[i][j] !='*')
{
cout<<a[i][j];
}
}
if(tp == 1)
cout<<endl;
tp = 0;
}
tp = 0;
cout<<"Down"<<endl;
char tmp[100][100];
memset(tmp, 0, sizeof(tmp));
int tpj = 0;
int g;
for(int j = 0; j< lcolumn; j++)
{
for(int i = 0; i < lrow; i++)
{
if(tp == 0 && a[i][j] !='*')
{
g = vis[i][j];
tmp[g][tpj++] = a[i][j];
tp =1;
}
else if(a[i][j] == '*' && tp == 1)
{
tp = 0;
tpj = 0;
}
else if(tp == 0 && a[i][j] =='*')
{
tpj = 0;
continue;
}
else if(tp == 1 && a[i][j] !='*')
{
tmp[g][tpj++] = a[i][j];
}
}
tpj = 0;
tp = 0;
}
for(int i = 0; i<100; i++)
{
if(tmp[i][0] != 0)
{
printf("%3d.", i);
for(int j = 0; tmp[i][j] !=0;j++)
{
cout<<tmp[i][j];
}
cout<<endl;
}
}
}
return 0;
}
DNA 序列 DNA Consensus String Uva 1368
总结:这道题用到了一个贪心的策略,就是在几个序列中出现最多的字符就是我们需要的那一个字符,如果所有字符出现的次数都一样,那就任选一个。
#include<iostream>
#include<cstring>
using namespace std;
char a[50][1010];
int vis[10];
int tmp[1020];
int main()
{
int t;
cin>>t;
while(t--)
{
int len;
int times;
cin>>times>>len;
for(int i = 0; i<times; i++)
{
scanf("%s", a[i]);
}
//ACGT;
int sum = 0;
for(int i = 0; i<len;i++)
{
memset(vis, 0, sizeof(vis));
for(int j = 0; j<times; j++)
{
if(a[j][i] == 'A')
{
vis[0]++;
}
else if(a[j][i] == 'C')
{
vis[1]++;
}
else if(a[j][i] == 'G')
{
vis[2]++;
}
else if(a[j][i] == 'T')
{
vis[3]++;
}
}
int maxn = vis[0];
int tpi = 0;
for(int z = 1; z<4;z++)
{
if(maxn < vis[z])
{
maxn = vis[z];
tpi = z;
}
}
tmp[i] = tpi;
for(int p = 0; p<4;p++)
{
if(p != tpi)
{
sum += vis[p];
}
}
}
for(int i = 0; i<len;i++)
{
if(tmp[i] == 0)
cout<<"A";
if(tmp[i] == 1)
cout<<"C";
if(tmp[i] == 2)
cout<<"G";
if(tmp[i] == 3)
cout<<"T";
}
cout<<endl;
cout<<sum<<endl;
}
return 0;
}
循环小数 Repeating Decimals Uva 202
总结:只要余数有重复的,说明开始循环。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[10000000];
int vis[10000000];
int main()
{
int bc,cs;
int bb, cc;
while(cin>>bb>>cc)
{
bc = bb;
cs = cc;
int len = 0;
int zs = bc /cs;
bc = bc % cs;
memset(vis, -1 ,sizeof(vis));
bc *= 10;
vis[bc] = 0;
a[len++] = bc / cs;
bc = bc % cs;
int cnt;
while(1)
{
bc*=10;
if(vis[bc] != -1)
{
//cout<<len-vis[bc]<<endl;;
cnt = len - vis[bc];
break;
}
vis[bc] = len;
a[len++] = bc / cs;
bc = bc % cs;
}
printf("%d/%d = %d.",bb,cc,zs);
for(int i = 0; i<vis[bc]; i++)
cout<<a[i];
cout<<"(";
if(cnt <50)
for(int i = 0;i<cnt;i++)
cout<<a[vis[bc]+i];
else
{
for(int i = 0;i<50;i++)
cout<<a[vis[bc]+i];
cout<<"...";
}
cout<<")\n";
printf(" %d = number of digits in repeating cycle\n\n", cnt);
}
return 0;
}
子序列 All in All Uva 10340
总结:有点相当然了,一开始写得有点简单,wa了几次,其实不难,中间条件写好就行,vis数组是存是否匹配。
#include<iostream>
#include<cstring>
using namespace std;
char s[100000];
char a[100000];
int vis[100000];
int main()
{
while(scanf("%s",s) != EOF)
{
scanf("%s",a);
int slen = strlen(s);
memset(vis,0 ,sizeof(vis));
int alen = strlen(a);
int j = 0;
int i = 0;
for( i; i <slen; )
{
for(j; j < alen; j++)
{
if(s[i] == a[j])
{
vis[i] = 1;
j++;
i++;
break;
}
}
if(j == alen )
break;
}
if(vis[slen-1] == 1)
cout<<"Yes\n";
else
cout<<"No\n";
}
return 0;
}
盒子 Box Uva 1587
总结:长方体只有长宽高三个属性,只要把输入处理好一比较就能得出答案。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node{
int x,y;
};
bool cmp(Node a, Node b)
{
return a.x != b.x ? a.x <b.x :a.y > b.y;
}
bool isok(Node a[6])
{
if(a[0].x != a[1].x ||a[2].x != a[3].x || a[4].x != a[5].x ||a[0].y != a[1].y || a[2].y != a[3].y|| a[4].y != a[5].y)
return false;
if(a[0].x != a[2].x || a[0].y != a[4].y ||a[2].y != a[4].x)
return false;
return true;
}
int main()
{
Node a[6];
int x, y;
while(scanf("%d%d", &x,&y) != EOF)
{
a[0].x = x;
a[0].y = y;
if(a[0].x > a[0].y)
swap(a[0].x, a[0].y);
for(int i = 1; i<6; i++)
{
scanf("%d%d", &x, &y);
a[i].x = x;
a[i].y = y;
if(a[i].x > a[i].y)
swap(a[i].x, a[i].y);
}
sort(a,a+6, cmp);
if(isok(a))
{
printf("POSSIBLE\n");
}
else{
printf("IMPOSSIBLE\n");
}
}
return 0;
}
换抵挡装置 Kickdown uva 1588
总结:这道题的关键是有左移和右移,如果没考虑到这个的话,肯定wa,左移和右移的代码也非常的简单,一个双重循环就行。
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char c[200];
char d[200];
int solve(char a[200], char b[200])
{
int alen = strlen(a);
int blen = strlen(b);
int i = 0, j= 0;
int flag = 0;
int len ;
for(i ; i<alen; )
{
for(j ; j<blen;)
{
int tpa = a[i+j] - '0';
int tpb = b[j] - '0';
if(tpa + tpb <= 3)
{
j++;
}
else if(tpa + tpb > 3)
{
flag++;
i = flag;
j = 0;
}
if(i +j >= alen)
{
return flag + blen;
}
}
if(i == alen)
{
len = flag + blen;
return len;
}
else if(j == blen)
{
len = alen;
return len;
}
}
return 0;
}
int main()
{
while(scanf("%s", c)!=EOF)
{
scanf("%s",d);
int sy, xy;
xy = solve(c,d);
sy = solve(d,c);
cout<<min(xy,sy)<<endl;
}
return 0;
}
浮点数 Floating - Point Numbers Uva 11809
搞不是很定,后面再补题