8.12 打的小白赛,题如期名,全是简单题和模板题,算是给后面的机考练练手,也算是了解了校内的水平,暑假因为其他事牵扯的关系,没有好好学习算法,没有好好完成计划,希望以后能够更加认真的学习算法。
A - A + B
//杭电1228 模拟
//题意给定例如three four + five six =
//输出A+B
//由于刚开始习惯性看第一题,没有解决输入问题,打了一遍代码案例过不了就跳题
//过后一天才补回来
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main()
{
map<string ,int>q;
q["one"]=1;q["two"]=2;q["three"]=3;q["four"]=4;q["five"]=5;
q["six"]=6;q["seven"]=7;q["eight"]=8;q["nine"]=9;q["ten"]=10;
string s;
while(1)
{
int a=0,b=0;
while(cin>>s&&s!="=")
{
if(s!="+") a=a*10+q[s];
else b=a,a=0;
}
if(a==0&&b==0) break;
else cout<<a+b<<endl;
}
return 0;
}
B - 3n + 1?
//POJ 1207 模拟
//若n为偶数,则n=n/2;否则n=n*3+1
//给定一个区间[l,r]求最多的操作数
//坑点:l r没有一定的大小关系 最后答案的输出必须原区间
#include<iostream>
using namespace std;
const int manx=1e4+5;
int a[manx],b[manx];
int main()
{
int l,r;
std::ios::sync_with_stdio(false);
while(cin>>l>>r)
{
int ans,res,maxx=-1;
for(int i=min(l,r);i<=max(l,r);i++){
res=i,ans=1;
if(res==0) ans=0;
while(res>1)
{
if(res%2==1) res=res*3+1;
else res/=2;
ans++;
}
if(ans>maxx) maxx=ans;
}
cout<<l<<" "<<r<<" "<<maxx<<endl;
}
return 0;
}
最爱字符串
//HihoCoder - 1485 尺取法/滑动窗口/双指针
//求字符串中含有2个"h" 1个"i" 1个"o" 的最短子串
//没听过尺取法/滑动窗口,本来想用双指针做,后面时间不够就没有写,赛后补了回来
#include<iostream>
#include<string>
#include<map>
using namespace std;
const int manx=1e5+5;
struct node
{
int pos; //记录位置
char c; //记录所在位置的字符
}a[manx];
int main()
{
string s;
cin>>s;
map<char ,int >q;
int ans=manx,p=0;
for(int i=0;i<s.size();i++)
if(s[i]=='h'||s[i]=='o'||s[i]=='i')
{
p++;
a[p].c=s[i];
a[p].pos=i;
}
int head=1;
for(int i=1;i<=p;i++)
{
if(i<=4) q[ a[i].c ]++;
else {
q[ a[head].c] --;
q[ a[i].c ] ++;
head++;
}
if(q['h']==2 && q['o']==1 && q['i']==1)
ans=min(ans,a[i].pos-a[head].pos+1);
}
if(ans!=manx) cout<<ans<<endl;
else cout<<-1;
return 0;
}
D - 序列和
// hdu 1231 dp经典
//比子序列问题多了求初始位置和终止位置 也就多了一个比较过程
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int manx=1e4+5;
int a[manx],dp[manx];
int main()
{
int n;
while(cin>>n&&n)
{
for(int i=1;i<=n;i++)
cin>>a[i];
int l=0,r=0,ll,rr,ans=-1;
for(int i=1;i<=n;i++)
{
if(i==1) ans=dp[1]=a[1],ll=i,rr=i;
else dp[i]=max(dp[i-1]+a[i],a[i]);
if(dp[i]==a[i]) l=i,r=i;
else r=i;
if(dp[i]>ans) ans=dp[i],ll=l,rr=r;
}
if(ans<0) ans=0,ll=1,rr=n;
cout<<ans<<" "<<a[ll]<<" "<<a[rr]<<endl;
}
return 0;
}
E - 迷宫
//poj 3984
//伪AC代码 本题考查广搜?深搜? 输出最短路径数并输出路径
//由于本人喜爱深搜但又不会广搜,所以用深搜大法师水了一发
//注意dx和dy数组的设置,一定要先往右边和先往下边走,这样好占数据的便宜,数据一弱就过了
//等学完广搜再补回来
#include<iostream>
#include<vector>
using namespace std;
int a[6][6],check[6][6],dx[4]={0,1,-1,0},dy[4]={1,0,0,-1};
int bestValue=25;
vector<int> path;
vector<int> tempPath;
void DFS(int v,int p,int value){
tempPath.push_back(v);
tempPath.push_back(p);
if(v == 4&& p==4 ){
if(value < bestValue){
bestValue = value;
path = tempPath;
}
return ;
}
for(int i=0;i<4;i++){
if( a[v+dx[i]][p+dy[i]] && !check[v+dx[i]][p+dy[i]])
{
check[v+dx[i]][p+dy[i]]=1;
DFS(v+dx[i],p+dy[i],value++);
check[v+dx[i]][p+dy[i]]=0;
}
}
tempPath.pop_back();
tempPath.pop_back();
}
int main()
{
int m;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
{
cin>>m;
if(m) a[i][j]=0;
else a[i][j]=1;
}
DFS(0,0,0);
for(int i=0;i<path.size();i++)
{
if(i%2==0) cout<<"("<<path[i]<<", ";
else cout<<path[i]<<")"<<endl;
}
return 0;
}
F - 布阵
//hdu 1166
//线段树模板题 考察区间查询和单点修改
//模板贴上去打上return 0 1分钟AC一气呵成
#include<iostream> //线段树模板
#include<cstdio>
using namespace std;
typedef long long ll;
const int manx=100010;
ll n,p,a,b,m,x,y,ans;
ll aa[manx+5];
struct node
{
ll l,r,w,f;
}tree[4*manx];
inline void build(ll k,ll l,ll r)//建树
{
tree[k].l=l,tree[k].r=r;
if(tree[k].l==tree[k].r)
{
tree[k].w=aa[l];
return;
}
int m=(l+r)/2;
build(k*2,l,m);
build(k*2+1,m+1,r);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
inline void down(ll k)//标记下传
{
tree[k*2].f+=tree[k].f;
tree[k*2+1].f+=tree[k].f;
tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
tree[k].f=0;
}
inline void ask_point(ll k)//单点查询
{
if(tree[k].l==tree[k].r)
{
ans=tree[k].w;
return ;
}
if(tree[k].f) down(k);
int m=(tree[k].l+tree[k].r)/2;
if(x<=m) ask_point(k*2);
else ask_point(k*2+1);
}
inline void change_point(ll k)//单点修改
{
if(tree[k].l==tree[k].r)
{
tree[k].w+=y;
return;
}
if(tree[k].f) down(k);
int m=(tree[k].l+tree[k].r)/2;
if(x<=m) change_point(k*2);
else change_point(k*2+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
inline void ask_interval(ll k)//区间查询
{
if(tree[k].l>=a&&tree[k].r<=b)
{
ans+=tree[k].w;
return;
}
if(tree[k].f) down(k);
int m=(tree[k].l+tree[k].r)/2;
if(a<=m) ask_interval(k*2);
if(b>m) ask_interval(k*2+1);
}
inline void change_interval(ll k)//区间修改
{
if(tree[k].l>=a&&tree[k].r<=b)
{
tree[k].w+=(tree[k].r-tree[k].l+1)*y;
tree[k].f+=y;
return;
}
if(tree[k].f) down(k);
int m=(tree[k].l+tree[k].r)/2;
if(a<=m) change_interval(k*2);
if(b>m) change_interval(k*2+1);
tree[k].w=tree[k*2].w+tree[k*2+1].w;
}
int main()
{
int t;
cin>>t;
for(int p=1;p<=t;p++)
{
cout<<"Case "<<p<<":"<<endl;
cin>>n;
for(int i=1;i<=n;i++)
cin>>aa[i];
build(1,1,n);//建树
string s;
while(cin>>s){
ans=0;
if(s[0]=='Q')
{
scanf("%lld%lld",&a,&b);
ask_interval(1);
printf("%lld\n",ans);
}
else if(s[0]=='S')
{
scanf("%lld%lld",&x,&y);
y*=-1;
change_point(1);
}
else if(s[0]=='A')
{
scanf("%lld%lld",&x,&y);
change_point(1);
}
else break;
}
}
return 0;
}
G - 鸡你太美
//poj 1611
//并查集 模板题
//有一群人 分成几个小团体 只要有人病患的团体全部病患 一开始只有0患病
//查找0是爸爸的个数
#include<iostream>
using namespace std;
const int manx=3e4+5;
int a[manx];
int find(int x)
{
if(a[x]==x) return x;
else return a[x]=find(a[x]);
}
int main()
{
int n,m,p,x,y,ans=0;
std::ios::sync_with_stdio(false);
while(cin>>n>>m&& (m||n))
{
for(int i=0;i<n;i++)
a[i]=i;
while(m--)
{
cin>>p>>x;
for(int i=1;i<p;i++)
{
cin>>y;
a[find(x)]=find(y);
x=y;
}
}
for(int i=0;i<n;i++)
if(find(a[i])==find(0))
ans++;
cout<<ans<<endl;
ans=0;
}
}
J - 数论大定理
// hud 6441
//费马大定理
//a^n+b^n=c^n 当n>2时无解 350年来的智商接力
//其中n=2时 有:
//若a = 2 * k + 1,则 c = k ^ 2 + ( k + 1 ) ^ 2 ,b = c - 1
//若a = 2 * k + 2,则 c = 1 + (k + 1) ^ 2 , b = c - 2
#include <cstdio>
#define ll long long
ll T, a, b, c, n;
int main(){
scanf("%lld", &T);
while(T--){
scanf("%lld %lld", &n, &a);
if(n == 2){
if(a%2){
ll t = (a-1)/2;
c = t*t+(t+1)*(t+1);
b = c-1;
}
else{
ll t = (a+2)/2;
c = 1+(t-1)*(t-1);
b = c-2;
}
printf("%lld %lld\n", b, c);
}
else if( n == 1){
printf("1 %lld\n", a+1);
}
else{
printf("-1 -1\n");
}
}
}
K - 有向图
// hdu 1269
// 强连通图的判断
// 这里我是用两个并查集 一个从1到n 一个从n到1 进行判定连通性
#include<iostream>
#include<cmath>
#include<string>
#include<cstdio>
using namespace std;
const int manx=1e4+5;
int a[4][manx];
int n,m;
int find(int x,int i)
{
return x==a[i][x]?x:a[i][x]=find(a[i][x],i);
}
void fun(int x,int y)
{
if(x!=n){
int xx=find(x,1);
int yy=find(y,1);
if(xx!=yy) a[1][x]=y; //把y放在x的后面
}
if(y!=n)
{
int xx=find(x,2);
int yy=find(y,2);
if(xx!=yy) a[2][y]=x; //把x放在y的后面
}
}
int main()
{
while(scanf("%d %d",&n,&m)!=EOF&&(m||n))
{
int b,c,flag=1;
for(int i=1;i<=2;i++)
for(int j=1;j<=n;j++)
a[i][j]=j;
for(int i=1;i<=m;i++)
scanf("%d",&b),scanf("%d",&c),fun(b,c);
for(int i=1;i<=n;i++)
{
if(find(i,1)!=n||find(i,2)!=n)
{
flag=0;
break;
}
}
if(flag) printf("Yes\n");
else printf("No\n");
}
return 0;
}
L - 钱币兑换
//hdu1284 dp
//完全背包问题 没啥好说
#include<iostream>
using namespace std;
const int manx=32768;
long long dp[32768];
int main()
{
dp[0]=1;
for(int i=1;i<=3;i++)
for(int j=1;j<=manx;j++)
dp[j]+=dp[j-i];
int n;
std::ios::sync_with_stdio(false);
while(cin>>n)
{
cout<<dp[n]<<endl;
}
return 0;
}
M - 又是A+B
//hdu 2524 思维+模拟
//求矩形个数
//行列分割 可以发现跟小学时代求三角形个数一样
//都是从1+2+……+n
//可以得到n行m列的公式为:n*(n+1)/2*m*(m+1)/2
#include<iostream>
#include<map>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--)
{
int a,b;
cin>>a>>b;
cout<<a*(a+1)/2*b*(b+1)/2<<endl;
}
return 0;
}
N - 素数
//hdu 1262 模拟+素数
//对于每个偶数,输出两个彼此最接近的素数,其和等于该偶数
//打完素数表后枚举就可以了
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int manx=1e4+5;
bool prime[manx];
void make_prime()
{
memset(prime,true,sizeof(prime));
prime[0]=prime[1]=false;
int t=sqrt(manx);
for(int i=2;i<=t;i++)
{
if(prime[i])
for(int j=2*i;j<manx;j+=i)
{
prime[j]=false;
}
}
return;
}
int main()
{
make_prime();
int n;
while(cin>>n)
{
for(int i=n/2;i>0;i--)
if(prime[i]&&prime[n-i]){
cout<<i<<" "<<n-i<<endl;
break;
}
}
return 0;
}