【异世界情绪】日文翻唱《鳥の詩/鸟之诗》
引个流,情绪的鸟之诗真的好听,听着这个学习效率巨高!
文章目录
前言
这里2天写了些作业,算是对算法小入了个门,这里做个简单记录,理科生,写文章懂得都懂。将就看吧。
A - A + B Problem I(大数相加)
其实不难,直接利用string就行,关键是要模仿人类加减法时的写法就行,然后建议把末位存到数组首位,这样的话rst多出来的一位就可以直接用于进位
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <cmath>
#define PI 3.1415927
using namespace std;
int s1[1001]={0},s2[1001]={0},rst[1001]={0},jw=0,sw=0;
int cnt=0,Max;
int main()
{
int n;
cin>>n;
string str1,str2;
while(n--)
{
jw=0;
cin>>str1>>str2;
int maxlen=(str1.length()>str2.length())?str1.length():str2.length();
//上面是为了之后的进位
int x1=str1.length();
for(int i=0,j=x1-1;j>=0;i++,j--)
{s1[i]=str1[j]-48;}//-48是减去'0'从而变成数字
int x2=str2.length();
for(int i=0,j=x2-1;j>=0;i++,j--)
{s2[i]=str2[j]-48;}
for(int i=0;i<=maxlen;i++)
{
rst[i]=s1[i]+s2[i]+jw;
if(rst[i]>=10){jw=1;rst[i]%=10;}//考虑进位
else{jw=0;}
}
if(rst[maxlen]==0){Max=maxlen-1;}//如果结果的最高位==0rst就不用从maxlen读,相当没进位
else {Max=maxlen;}
cout<<"Case "<<++cnt<<":"<<endl;
cout<<str1<<" + "<<str2<<" = ";
for(int i=Max;i>=0;i--)
cout<<rst[i];
cout<<endl;
if(n)cout<<endl;
for(int i=0;i<=maxlen;i++)
{
s1[i]=s2[i]=rst[i]=0;
}
}
return 0;
}
B - 开门人和关门人(sort,cmp,scanf和printf)
没啥说的,就是sort和c风格还有sort规则编写,有一说一scanf和printf确实香,直接给你规定格式怎么说嘛!
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <cmath>
#include <vector>
#include <cstdio>
#define PI 3.1415927
using namespace std;
struct x
{
char name[15];
int stime;
int etime;
}record[1000];
bool cmp1(x&a,x&b)
{
return a.stime<b.stime;
}
bool cmp2(x&a,x&b)
{
return a.etime>b.etime;
}
int main()
{
int n;
cin>>n;
while(n--)
{
int M,h,m,s;
cin>>M;
for(int i=0;i<M;i++)
{
scanf("%s %d:%d:%d",record[i].name,&h,&m,&s);
record[i].stime=h*3600+m*60+s;
scanf("%d:%d:%d",&h,&m,&s);
record[i].etime=h*3600+m*60+s;
}
sort(record,record+M,cmp1);
cout<<record[0].name<<" ";
sort(record,record+M,cmp2);
cout<<record[0].name<<endl;
}
return 0;
}
C - Oil Deposits (dfs)
正在写,关键是方向离谱,没人说明,后面才发现简单
说白了就是8个方向坐标(1,0)(1,1)(0,1)(-1,1)(-1,0)(-1,-1)(0,-1)(1,-1)罢了。
这道题没用到回溯的原因是,他一边找一边更新了图,所以没用到了。
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <cmath>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstring>
#define PI 3.1415927
using namespace std;
int nsjfx[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
char Map[101][101];
int m,n;
//逆时针从x轴方向开始的八个方向
void dfs(int x,int y)
{
if(Map[x][y]=='@')Map[x][y]='*';//标记,防止再搜
for(int i=0;i<8;i++)
{
int a=nsjfx[i][0]+x;//横坐标
int b=nsjfx[i][1]+y;//纵坐标
if(Map[a][b]=='@'&&a<m&&a>=0&&b<n&&b>=0)
dfs(a,b);
}
}
int main()
{
while(cin>>m)
{
if(m==0)break;
cin>>n;
int cnt=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
cin>>Map[i][j];
}
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(Map[i][j]=='@')
{
dfs(i,j);
cnt++;
}
}
}
cout<<cnt<<endl;
cnt=0;
}
return 0;
}
D - A strange lift(bfs)
不难,bfs个人认为比dfs简单,边摸绳结边走路,最后选绳结最少的路谁不会呢?
这里提一嘴,-1的情况是真的牛,直接利用了最后面那个判断再给你-1怎么说嘛,诶,帅的不谈~
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <cmath>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstring>
#define PI 3.1415927
using namespace std;
int bs[1001],flag[1001];
void bfs(int x,int y)
{
queue<int>q;
q.push(x);
flag[x]=1;//我的初始位置
int t,next;
while(!q.empty())//q内有数时
{
t=q.front();//最开始t=x,层数
q.pop();//去除首位,此时q内无东西
if(t==y)break;
next=t+bs[t];//向上到哪
if(next<=y&&flag[next]==0)//==0是为了确保不重复记录,<=y防止越界
{
q.push(next);
flag[next]=flag[t]+1;
}
next=t-bs[t];
if(next>=1&&flag[next]==0)
{
q.push(next);
flag[next]=flag[t]+1;
}
}
if(t!=y)flag[y]=0;
}
int main()
{
int N,a,b;
while(cin>>N)
{
if(N==0)break;
cin>>a>>b;
for(int i=1;i<=N;i++)
{
cin>>bs[i];
}
memset(flag,0,sizeof(flag));
bfs(a,b);
cout<<flag[b]-1<<endl;//这里也解决了-1的情况
}
return 0;
}
E - Monthly Expense(最大值最小化的二分)
这道题,我最开始看,好家伙别人都说最大值最小化然后二分。最大值最小化???属实没懂,后面理解。用人话来说就是分多个块,但是有许多不同的分法,每种分法里面总有一个块的和最大。你要找的就是这个和最大的集合里最小的那个。
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <cmath>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstring>
#define PI 3.1415927
using namespace std;
int bs[1001],flag[1001];
void bfs(int x,int y)
{
queue<int>q;
q.push(x);
flag[x]=1;//我的初始位置
int t,next;
while(!q.empty())//q内有数时
{
t=q.front();//最开始t=x,层数
q.pop();//去除首位,此时q内无东西
if(t==y)break;
next=t+bs[t];//向上到哪
if(next<=y&&flag[next]==0)//==0是为了确保不重复记录,<=y防止越界
{
q.push(next);
flag[next]=flag[t]+1;
}
next=t-bs[t];
if(next>=1&&flag[next]==0)
{
q.push(next);
flag[next]=flag[t]+1;
}
}
if(t!=y)flag[y]=0;
}
int main()
{
int N,a,b;
while(cin>>N)
{
if(N==0)break;
cin>>a>>b;
for(int i=1;i<=N;i++)
{
cin>>bs[i];
}
memset(flag,0,sizeof(flag));
bfs(a,b);
cout<<flag[b]-1<<endl;//这里也解决了-1的情况
}
return 0;
}
F - Super Jumping! Jumping! Jumping! (dp)
dp罢了,其实吧dp对我来说不难,难得是递归。这个东西对我来说是个玄学,有时候一下就能理解就比如对I题的快速find求根一样简单,又时候就怎么都想不明白。
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <cmath>
#include <vector>
#include <cstdio>
#include <queue>
#include <cstring>
#define PI 3.1415927
using namespace std;
int dp[10000],gj[10000];
int main()
{
int n;
while(cin>>n)
{
if(n==0)break;
int Max=0;
for(int i=0;i<n;i++)
{
cin>>gj[i];
}
memset(dp,0,sizeof(dp));
dp[0]=gj[0];//初始化dp啊,傻逼,粗心是吧
for(int i=1;i<n;i++)//这里两个for是为了取相对大的和菜这样设置
{
dp[i]=gj[i];
for(int j=0;j<i;j++)
{
if(gj[i]>gj[j])dp[i]=max(dp[i],dp[j]+gj[i]);
}
}
for(int i=0;i<n;i++)
Max=max(dp[i],Max);
cout<<Max<<endl;
}
return 0;
}
G - 矩形A + B(找规律)
高中数学题罢了不谈。
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <cmath>
#include <vector>
#include <cstdio>
#define PI 3.1415927
using namespace std;
int main()
{
int t,n,m;
cin>>t;
while(t--)
{
cin>>n>>m;
cout<<n*(n+1)/2*m*(m+1)/2<<endl;
}
return 0;
}
H - FatMouse’ Trade(贪心)
贪心(小擅长?我个人挺喜欢像这样快速解决问题的),这个我最开始没考虑性价比,直接先把价格最低的吃掉,然后更新相关数据,结果wa了,后面考虑到了要用性价比
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <cmath>
#include <vector>
#include <cstdio>
#define PI 3.1415927
using namespace std;
double cnt=0;
struct dz
{
double j;
double f;
double xjb;
}sk[1001];
bool cmp(dz a,dz b)
{
return a.xjb>b.xjb;
}
int main()
{
int n,m;
while(cin>>m>>n)
{
if(n==-1&&m==-1)break;
for(int i=0;i<n;i++)
{
cin>>sk[i].j>>sk[i].f;
sk[i].xjb=sk[i].j/sk[i].f;
}
sort(sk,sk+n,cmp);
for(int i=0;i<n;i++)
{
if(m>=sk[i].f){cnt+=sk[i].j;m-=sk[i].f;}
else{cnt+=sk[i].xjb*m;m=0;}
}
cout<<fixed<<setprecision(3)<<cnt<<endl;
cnt=0;
}
return 0;
}
I - How Many Tables(并查集)
并查集,这里就是要弄清楚join和find的作用即关系
#include <iostream>
#include <algorithm>
#include <string>
#include <iomanip>
#include <cmath>
#include <vector>
#include <cstdio>
#define PI 3.1415927
using namespace std;
int friends[1001],Rank[1001],cnt=0;
void psonset(int n)
{
for(int i=1;i<=n;i++)
{
friends[i]=i;
Rank[i]=i;
}
}
int Find(int x)//找根节点的快速方法
{
if(friends[x]==x)return x;
return friends[x]=Find(friends[x]);
}
void join(int x,int y)//让没关系的人合在一起
{
if(Find(x)!=Find(y))
{
friends[Find(x)]=Find(y);
}
}
int main()
{
int t;
cin>>t;
int n,m,u,v;
while(t--)
{
cin>>n>>m;
psonset(n);//设置人员
for(int i=0;i<m;i++)
{
cin>>u>>v;
join(u,v);
}
for(int i=1;i<=n;i++)//找有多少个根节点,就是桌子数
{
if(Find(i)==i)cnt++;
}
cout<<cnt<<endl;
cnt=0;
}
return 0;
}