ACM-ICPC在线模板
题单链接:
【算法1-1】模拟与高精度
下面的这一坨都是洛谷题单上的东东
恭喜大家完成了第一部分语言入门,相信大家已经可以使用 C++ 写出一些简单程序了。
各位读者有听说过“建模”一词吗?所谓“建模”,就是把事物进行抽象,根据实际问题来建立对应的数学模型。“抽象”并不意味着晦涩难懂;相反,它提供了大量的便利。计算机很难直接去解决实际问题,但是如果把实际问题建模成数学问题,就会大大地方便计算机来“理解”和“解决”。
举个生活中常见的例子:我们拿到了某次数学考试的成绩单,现在需要知道谁考得最好。当然不能把成绩单对着电脑晃一晃,然后问“谁考得最好?”。需要通过一种途径让计算机来理解这个问题。这个问题可以建模成:“给定数组
score[]
,问数组内元素的最大值”。这样建模后,就能很方便的写程序解决问题了。对于这个问题,采用之前讨论过的“擂台法”,就可以给出答案。
如何把实际问题建模成数学问题,主要依靠我们的经验和直觉、当然还有你灵动的思维;而算法与数据结构,正是解决数学问题的两把利剑。从这一章开始会介绍一些程序设计竞赛中的一些常见套路算法,而下一部分会介绍基础的数据结构。如果已经认真学习完了第一部分,相信这一部分也不在话下。
这一章是语言部分的延伸,会介绍一些竞赛中会出现的“模拟题目”——这里的“模拟”不是指模拟某场比赛的模拟题,而是指让程序完整的按照题目叙述的方式执行运行得到最终答案。同时也会介绍可以计算很大整数的高精度运算方法。这一章对思维与算法设计的要求不高,但是会考验编程的基本功是否扎实。
碎碎念
洛谷的新出两个月 的题单,正好从基础刷起,我还是太菜了,今天周三,周日之前刷完这一题单,一共16道题,应该全都是水题,正好练一下手速。模拟和高精,python大法好。但是C++的高精还是需要练一下,毕竟有时候python的熟练度不够,有的程序不好写。这周就差不多了,然后牛客有比赛就打一下,codeforce都太晚了,半夜刷题不要命辣,还有高数和大物的作业要写,英语的听力也要练,我太难了,好了,就这样。
P1042 乒乓球
水完啦,一分钟写一下题解。
水题一号,字符串处理,只需要记一下数就好,但是别忘了循环完了再写一个printf因为不是正好结束比赛,还有新开的几把,有没有输出的比分。
#include
#include
#include
#include
#include
#include
#include
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l+r)/2
#define over(i,s,t) for(register long long i=s;i<=t;++i)
#define lver(i,t,s) for(register long long i=t;i>=s;--i)
//#define int __int128
using namespace std;
typedef long long ll;//全用ll可能会MLE或者直接WA,试着改成int看会不会A
const ll N=750007;
const ll INF=1e10+9;
const ll mod=2147483647;
const double EPS=1e-10;//-10次方约等于趋近为0
const double Pi=3.1415926535897;
ll n,m,a[N];
char ch;
char s[N];
ll ansa,ansb,tot;
int main()
{
while(scanf("%c",&ch)&&ch!='E')
{
if(ch=='W')ansa++,s[tot++]=ch;
if(ch=='L')ansb++,s[tot++]=ch;
if((ansa>=11||ansb>=11)&&abs(ansa-ansb)>=2)
{
printf("%lld:%lld\n",ansa,ansb);
ansa=0;
ansb=0;
}
}
printf("%lld:%lld\n\n",ansa,ansb);
ansa=0,ansb=0;
over(i,0,tot-1)
{
if(s[i]=='W')ansa++;
if(s[i]=='L')ansb++;
if((ansa>=21||ansb>=21)&&abs(ansa-ansb)>=2)
{
printf("%lld:%lld\n",ansa,ansb);
ansa=0;
ansb=0;
}
}
printf("%lld:%lld\n",ansa,ansb);
return 0;
}
P2670 扫雷游戏
吓人,入门题给我搞DFS,花了5分钟水了一下。
这道题看上去第一反应就是DFS,直接八个方向搜就好,数据贼小,正好复习一下dfs。A完看了一眼题解,有不用dfs做的方法,直接用一个布尔数组判断,输出的时候把八个方向上相邻的数加起来就好,刚刚倒是没想到还可以这样水题
#include
#include
#include
#include
#include
#include
#include
#define ls (p<<1)
#define rs (p<<1|1)
#define mid (l+r)/2
#define over(i,s,t) for(register long long i=s;i<=t;++i)
#define lver(i,t,s) for(register long long i=t;i>=s;--i)
//#define int __int128
using namespace std;
typedef long long ll;//全用ll可能会MLE或者直接WA,试着改成int看会不会A
const ll N=105;
const ll INF=1e10+9;
const ll mod=2147483647;
const double EPS=1e-10;//-10次方约等于趋近为0
const double Pi=3.1415926535897;
ll n,m;
char mp[N][N];
ll ans[N][N];
void dfs(ll x,ll y)
{
over(dx,-1,1)over(dy,-1,1)
{
ll nx=x+dx,ny=y+dy;
if(nx<=n&&nx>0&&ny<=m&&ny>0&&mp[nx][ny]!='*')
ans[nx][ny]++;
}
}
int main()
{
scanf("%lld%lld",&n,&m);
over(i,1,n)over(j,1,m)
{
cin>>mp[i][j];
if(mp[i][j]=='*')
dfs(i,j);
}
over(i,1,n)over(j,1,m)
{
if(mp[i][j]=='*')
printf("%c",mp[i][j]);
else printf("%lld",ans[i][j]);
if(j==m)puts("");
}
return 0;
}
附:那位不用dfs大佬的代码
#include
using namespace std;
bool a[105][105];//一张地图,有雷为一,无雷为零
int main()
{
memset(a,0,sizeof(a));//地图最开始清空
int n,m;
char tmp;
cin>>n>>m;
for(int i=1;i<=n;i++)//读入地图
{
for(int j=1;j<=m;j++)
{
cin>>tmp;//读入每一个点
if(tmp=='*') a[i][j]=1;//如果是地雷就将这个点设为一
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i][j]==1) printf("*"); //如果是地雷不用输出数字
else
{
printf("%d",a[i+1][j+1]+a[i+1][j-1]+a[i+1][j]+a[i][j+1]+a[i][j-1]+a[i-1][j+1]+a[i-1][j]+a[i-1][j-1]);
//将旁边的雷加起来输出
}
}
printf("\n");
}
return 0;//愉快的结束了主程序
}
这么一对比我的头文件好长啊,这个博客要塞下16道题的代码,我还是把头文件减少一点吧。
a=int(input())
b=int(input())
print(a+b)
来个高精模板
#include
#include
#include
#include
using namespace std;
const int N = 1005;
struct bign
{
int len,s[N];
bign() { memset(s,0,sizeof(s)); len=1; }
bign(int num) { *this=num; }
bign(char *num) { *this=num; }
bign operator =(int num)
{
char c[N];
sprintf(c,"%d",num);
*this=c;
return *this;
}
bign operator =(const char *num)
{
len=strlen(num);
for (int i=0;i<len;i++) s[i]=num[len-1-i]-'0';
return *this;
}
string str()
{
string res="";
for (int i=0;i<len;i++) res=(char)(s[i]+'0')+res;
return res;
}
void clean()
{
while (len>1&&!s[len-1]) len--;
}
bign operator +(const bign &b)
{
bign c;
c.len=0;
for (int i=0,g=0;g||i<len||i<b.len;i++)
{
int x=g;
if (i<len) x+=s[i];
if (i<b.len) x+=b.s[i];
c.s[c.len++]=x%10;
g=x/10;
}
return c;
}
bign operator -(const bign &b)
{
bign c;
c.len=0;
int x;
for (int i=0,g=0;i<len;i++)
{
x=s[i]-g;
if (i<b.len) x-=b.s[i];
if (x>=0) g=0;
else{
x+=10;
g=1;
};
c.s[c.len++]=x;
}
c.clean();
return c;
}
bign operator *(const bign &b)
{
bign c;
c.len=len+b.len;
for (int i=0;i<len;i++) for (int j=0;j<b.len;j++) c.s[i+j]+=s[i]*b.s[j];
for (int i=0;i<c.len-1;i++) { c.s[i+1]+=c.s[i]/10; c.s[i]%=10; }
c.clean();
return c;
}
bool operator <(const bign &b)
{
if (len!=b.len) return len<b.len;
for (int i=len-1;i>=0;i--)
if (s[i]!=b.s[i]) return s[i]<b.s[i];
return false;
}
bign operator +=(const bign &b)
{
*this=*this+b;
return *this;
}
bign operator -=(const bign &b)
{
*this=*this-b;
return *this;
}
};
istream& operator >>(istream &in,bign &x)
{
string s;
in>>s;
x=s.c_str();
return in;
}
ostream& operator <<(ostream &out,bign &x)
{
out<<x.str();
return out;
}
int main(){
bign a,b,c;
ios::sync_with_stdio(false);
cin>>a>>b;
// cout<
// cout<
c=a+b;
cout<<c<<endl;
return 0;
}
舒服了舒服了
到时候打印了直接抄
a=int(input())
b=int(input())
print(a*b)