ACM-ICPC 2018 南京赛区网络预赛A B E J

/************  A.An Olympian Math Problem  ********************

题意:输入一个n,用S来表示S=1*1!+2*2!+······+(n-1)*(n-1)!,求S%n的结果
思路:打表找规律,列出前几项会发现ans=n-1,注意要开long long;

***************************************************************/
#include
using namespace std;
#define ll long long

int main()
{
    int t;
    cin>>t;
    while(t--){
        ll n;
        cin>>n;
        cout<
/*********************  B. The writing on the wall  **************************

题意:有一个n*m的矩阵,里面有一些黑矩阵,问这个矩阵有多少个不带黑矩阵的矩阵
思路:把每个小的矩阵都当作一个子矩阵的一个右下角,暴力搜索每个充当右下角的子
矩阵可以存在多少个不含黑块的子矩阵,对于每一列,子矩阵个数应该是之前遍历的
最短的高度累加起来,然后对于每个小矩阵求和

一个三层的for循环遍历整个矩阵,时间复杂度为O(n*m*m);
对于第一层循环,遍历n列的元素,表示为i;
对于第一个二层循环,表示对于该列元素对于每个位置所能够达到的最大高度;
对于第二个二层循环,遍历这列元素的每一个点(即当做右下角的矩阵)
对于第三层循环,即表示这以这个小矩形为右下角,遍历剩下高度的所有情况之和

ll ans=0;
for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++)
        if(Map[i][j]) up[j]=i;
    for(int j=1;j<=m;j++){
        int Min=0x3f3f3f3f;
        for(int k=j;k>0;k--){
            Min=min(Min,i-up[k]);
            ans+=(ll)Min;
        }
    }
}

****************************************************************************/
#include
using namespace std;
#define ll long long
#define met(a,b) memset(a,b,sizeof(a))

int Map[100005][105],up[105];

int main()
{
    int t,cas=0;
    scanf("%d",&t);
    while(t--){
        int n,m,k;
        met(Map,0);
        met(up,0);
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i0;k--){
                    Min=min(Min,i-up[k]);
                    ans+=(ll)Min;
                }
            }
        }
        printf("Case #%d: %lld\n",++cas,ans);
    }
    return 0;
}
/*************************   E. AC Challenge  *******************************

题意:有n道题目,每道题目对应有ai和bi两个分值,用time*ai+bi表示这个题目的
分值,其中time表示对应的第几个做这个题,每道题还有对应的前导题,即写这个
题目之前必须写的题目
思路:状压dp
    1.这个题目首先是二进制优化,2^20大概1e6的样子,每个题目有m道前导题,可以
先利用0不需要做1需要做来记录这个题目是否可以做以及题目做过之后的状态
    2.首先是输入以及预处理这个题可以做的前提条件,a b数组分别储存每个题目对应的
分数,d数组用一个n位的二进制表示做这道题目的前提条件,即d[i]+=1<<(x-1);
    3.定义一个最大的可能情况 int now=(1<
using namespace std;
#define maxn 1<<20
#define ll long long

ll dp[maxn];
int a[25],b[25],d[25];

int time(int x)
{
    int cnt=0;
    while(x){
        x-=x&-x;
        cnt++;
    }
    return cnt+1;
}

int main()
{
    int n,m;
    scanf("%d",&n);
    for(int i=0;i
/******************   J. Sum  *****************************

题意:f(n)定义为n=a*b这样分解的式子,其中a和b不能包含平方因子。
当a!=b时n=a*b和n=b*a算两个式子。t组测试,求f(1)+f(2)+f(3)+···+f(n)

题解:有如下结论
    1.若i是素数则f(i)=2;
    2.若i的某个质数因子个数大于等于2,则f(i)=0;就是说当某个因子个数
大于等于2的时候,所分解的a*b或b*a必定有一个数含有平方因子,即f(i)=0;
    3.若i=a*b且a和b不含相同因子,则f(i)=f(a)*(b);
    4.若i的质因子x的个数为2,f(i)=f(i/(x*x))即为去掉平方因子个数
    打表需要用欧拉筛法

**********************************************************/
#include
using namespace std;

const int maxn = 2e7+5;
bool vis[maxn]; //标记合数为true质数为false
int prime[maxn];//prime[0]存个数,后边存连续的质数
int ans[maxn];//结果

void solve()
{
    ans[1]=1;
    for(int i=2;i

 

你可能感兴趣的:(ACM-ICPC 2018 南京赛区网络预赛A B E J)