4月11日省赛,给自己加油!
矩阵翻硬币:给定n,m。这么大的数据很明显找规律。。。。打表处理小数据,代码:
int a[500][500];
int main(){
int n,m,ans;
int i,j,k,l;
while(scanf("%d%d",&n,&m)!=EOF){
memset(a,0,sizeof(a));
ans=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
for(k=1;k<=n;k++)
for(l=1;l<=m;l++)
if (k%i==0&&l%j==0)
a[k][l]^=1;
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
if (a[i][j]) ans++;
printf("%d ",a[i][j]);
}
puts("");
}
printf("%d\n\n",ans);
}
return 0;
}
发现只有平方数的地方不一样。。那么假设n中有a个平方数,m中有b个,答案就是a*b。直接上大数模版即可!或者用Java。。。
兰顿蚂蚁:模拟。看懂题目跟着做就好了。注意,题中已经规定好坐标从(0,0)开始算,对有Pascal习惯的童鞋。。。看清楚题目!
实现的小技巧:按照顺序(逆时针或者顺时针的方向)排列上下左右,在处理转弯的时候特别方便。上代码:
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
//方向为上,右,下,左
int map[200][200];
int main(){
int i,j;
char s[5];
scanf("%d%d",&m,&n);
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&map[i][j]);
scanf("%d%d%s%d",&x,&y,s,&k);
int dir;
if (s[0]=='U') dir=0;//初始的方向定好
else if (s[0]=='D') dir=2;
else if (s[0]=='L') dir=3;
else dir=1;
while(k--){
if (map[x][y]){//右转
map[x][y]=1-map[x][y];
dir=(dir+1)%4;
x+=dx[dir];
y+=dy[dir];
}
else{//白格,左转90
map[x][y]=1-map[x][y];
dir=(dir-1+4)%4;
x+=dx[dir];
y+=dy[dir];
}
}
printf("%d %d\n",x,y);
return 0;
}
分糖果:模拟啊。。。不知道多少次,那么判断一次如果不满足条件继续执行就好了
int a[maxn],b[maxn];
int ans,n;
void solve(){
int i;
for(i=0;i<n;i++){
b[(i+n-1)%n]=a[i]/2;
a[i]/=2;
}
for(i=0;i<n;i++){
a[i]+=b[i];
b[i]=0;
if (a[i]%2){
a[i]++;
ans++;
}
}
}
int main(){
int i,j,k;
while(scanf("%d",&n)!=EOF){
for(i=0;i<n;i++) scanf("%d",&a[i]);
ans=0;
while(1){
int flag=0;
for(i=1;i<n;i++)
if (a[i]!=a[0]){
flag=1;
break;
}
if (flag) solve();
else break;
}
printf("%d\n",ans);
}
return 0;
}
数字游戏:模拟题。注意数学符号%的使用,不需要真正按照循环报数去找,每次间隔的数有规律的,找到规律直接输出
num是每次报的数,看着式子肯定可以找到规律(从等差来想)
long long n,m,t,add,first,final,i,j,k,num,ans;
int main(){
//freopen("input.txt","r",stdin);
scanf("%I64d%I64d%I64d",&n,&k,&t);
ans=num=1;
for(i=0;i<t-1;i++){
first=i*n+1;
final=i*n+n;
add=(first+final)*n/2;
add=add%k;
num=(num+add)%k;
ans+=num;
}
printf("%I64d\n",ans);
}
回文数字:暴力算呗
const int maxn=1000050;
int ans[maxn],tot=0;
int main(){
int i,j,k,n;
scanf("%d",&n);
for(i=1;i<=9;i++)
for(j=0;j<=9;j++)
for(k=0;k<=9;k++){
if (2*i+2*j+k==n) ans[++tot]=i+j*10+k*100+j*1000+i*10000;
if (2*i+2*j+2*k==n) ans[++tot]=i+j*10+k*100+k*1000+j*10000+i*100000;
}
sort(ans+1,ans+1+tot);
for(i=1;i<=tot;i++)
printf("%d\n",ans[i]);
if (tot==0) puts("-1");
return 0;
}
买不到的数目:这道题是个数论结论题:答案为n*m-n-m
可以证明从n*m-n-m+1到无穷大的整数都可以用a*n+b*m表示
或者不知道结论就打表啊!!什么时候可以表示的数连续了,找到那个连续的数开始的位置,-1,就是答案。n和m都不大,是可以试试的。
连号区间数:不知道跟并查集有半毛钱关系。。。或者是我笨。。。
还是找的数学规律
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%d",&num[i]);
for(i=1;i<=n;i++){
int minnum=num[i];
int maxnum=num[i];
for(j=i;j<=n;j++){
minnum=min(num[j],minnum);
maxnum=max(num[j],maxnum);
if (maxnum-minnum==j-i) ans++;
//如果满足这个条件说明!!
}
}
printf("%d\n",ans);
return 0;
}
翻硬币:觉得算不上,贪心!就是从左到右循环一次来更改一次,直到目标状态
const int maxn=2000;
char s1[maxn],s2[maxn];
int a[maxn],b[maxn],ans;
int main(){
//freopen("input.txt","r",stdin);
scanf("%s%s",s1,s2);
ans=0;
int len=strlen(s1),i,j,k;
for(i=0;i<len;i++){
if (s1[i]=='o') a[i]=0;
else a[i]=1;
if (s2[i]=='o') b[i]=0;
else b[i]=1;
}
for(i=0;i<len;i++){
if (a[i]!=b[i]){
ans++;
a[i]=1-a[i];
a[i+1]=1-a[i+1];
}
}
printf("%d\n",ans);
return 0;
}
错误票据:这种题用map做好了啊,基础map使用,注意:如果重复的和连续的出现在一起啦。。细节条件判断
const int maxn=500;
int a[maxn];
map<int,int>mp;
int ans1,ans2,n,num,i,j,k,tot;
int main(){
//freopen("input.txt","r",stdin);
scanf("%d",&n);
mp.clear();
tot=0;
while(scanf("%d",&num)!=EOF){
a[tot++]=num;
mp[a[tot-1]]++;
}
sort(a,a+tot);
for(i=0;i<tot;i++)
if (mp[a[i]]==2){
ans2=a[i];
break;
}
for(i=0;i<tot;i++)
if (a[i]+1!=a[i+1]&&mp[a[i]]==1){
ans1=a[i]+1;
break;
}
printf("%d %d\n",ans1,ans2);
return 0;
}
带分数:最最自豪的一道题,感觉自己的代码无敌!
首先,此题肯定是个暴力题,怎么暴力。。。是个问题
N=A+B*C,表示成这样如果直接模拟算A,B,C,然后判重,然后判等,当然可以做,不过按照ACM的想法,考虑最大数据1000000不可能1s出解
注意,1-9的全排列可以完全表示出A,B和C
所以只需要表示出A,B和C。
Step1:生成1到9的全排列
Step2:将全排列的数组生成A和B和C
Step3:判等
代码如下:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <queue>
#include <stack>
using namespace std;
#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)
#define For1(i,a,b) for (i=a;i<b;i++)
#define For2(i,a,b) for (i=a;i<=b;i++)
#define Fill(x,a) memset(x,a,sizeof(x))
#define inf 99999999
#define pi 3.1415926535897932384626433832795028841971
int num[10],vis[10],n,ans=0;
void check(){
int i,j,a,b,c,num1,num2,num3;
for(i=1;i<=9;i++)
for(j=i+1;j<=9;j++){
num1=num2=num3=0;
for(a=1;a<=i;a++) num1=num1*10+num[a];
for(b=i+1;b<j;b++) num2=num2*10+num[b];
for(c=j;c<=9;c++) num3=num3*10+num[c];
if (num1+num2/num3==n&&num2%num3==0){
ans++;
//printf("%d %d %d\n",num1,num2,num3);
}
}
}
void dfs(int p){
if (p==10){
//for(int i=1;i<=9;i++) printf("%d%c",num[i],i==9?'\n':' ');
check();
return;
}
for(int i=1;i<=9;i++)
if (!vis[i]){
vis[i]=1;
num[p]=i;
dfs(p+1);
vis[i]=0;
}
return;
}
int main(){
int i,j,k;
scanf("%d",&n);
memset(vis,0,sizeof(vis));
dfs(1);
printf("%d\n",ans);
return 0;
}
由此方法,可以进一步得出打表的代码,如下:
注意判断范围在1000000以内!
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <queue>
#include <stack>
using namespace std;
#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)
#define For1(i,a,b) for (i=a;i<b;i++)
#define For2(i,a,b) for (i=a;i<=b;i++)
#define Fill(x,a) memset(x,a,sizeof(x))
#define inf 99999999
#define pi 3.1415926535897932384626433832795028841971
int num[10],vis[10],n;
int ans[1000050];
void check(){
int i,j,a,b,c,num1,num2,num3;
for(i=1;i<=9;i++)
for(j=i+1;j<=9;j++){
num1=num2=num3=0;
for(a=1;a<=i;a++) num1=num1*10+num[a];
for(b=i+1;b<=j-1;b++) num2=num2*10+num[b];
for(c=j;c<=9;c++) num3=num3*10+num[c];
if (num2%num3==0&&num1+num2/num3<=1000000) ans[num1+num2/num3]++;
}
}
void dfs(int p){
if (p==10){
//for(int i=1;i<=9;i++) printf("%d%c",num[i],i==9?'\n':' ');
check();
return;
}
for(int i=1;i<=9;i++)
if (!vis[i]){
vis[i]=1;
num[p]=i;
dfs(p+1);
vis[i]=0;
}
return;
}
int main(){
freopen("output.txt","w",stdout);
int i,j,k;
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
dfs(1);
for(i=1;i<=1000000;i++){
printf("%d,",ans[i]);
if (i%80==0) puts("");
}
//fclose(stdout);
//scanf("%d",&n);
//printf("%d\n",ans[n]);
return 0;
}